yet-another-gauge/4-20mA-Loop-Calibrator

GDB hangs with LibOpenCM3 on STM32F091RC

Closed this issue · 6 comments

(gdb) continue
Continuing.

^C
Program received signal SIGINT, Interrupt.
blocking_handler () at ../../cm3/vector.c:104
104		while (1);
(gdb)
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /Users/ivandyachenko/yet-another-gauge/4-20mA-Loop-Calibrator/build/4-20mA-Loop-Calibrator.elf
^C
Program received signal SIGINT, Interrupt.
blocking_handler () at ../../cm3/vector.c:104
104		while (1);
(gdb) info registers
r0             0x0                 0
r1             0x20                32
r2             0x48000000          1207959552
r3             0x8000560           134219104
r4             0xffffffff          -1
r5             0xffffffff          -1
r6             0xffffffff          -1
r7             0xffffffff          -1
r8             0xffffffff          -1
r9             0xffffffff          -1
r10            0xffffffff          -1
r11            0xffffffff          -1
r12            0xffffffff          -1
sp             0x20007fe0          0x20007fe0
lr             0xfffffff9          -7
pc             0x8000368           0x8000368 <blocking_handler>
xPSR           0x61000003          1627389955
msp            0x20007fe0          0x20007fe0
psp            0xfffffffc          0xfffffffc
primask        0x0                 0
basepri        0x0                 0
faultmask      0x0                 0
control        0x0                 0

Program Counter

The Program Counter (PC) is register R15. It contains the current program address. On
reset, the processor loads the PC with the value of the reset vector, at address
0x00000004. Bit[0] of the value is loaded into the Execution Program Status Register (EPSR) T-bit at reset and must be 1.

Program Status Register

The Program Status Register (PSR) combines:

  • Application Program Status Register (APSR)
  • Interrupt Program Status Register (IPSR)
  • Execution Program Status Register (EPSR).

These registers are mutually exclusive bitfields in the 32-bit PSR. The PSR bit
assignments are:
Screenshot 2019-10-06 at 18 17 03
Screenshot 2019-10-06 at 19 14 38

pc 0x8000368 0x8000368 <blocking_handler>
xPSR 0x61000003 1627389955

APSR. Negative flag = 0; zero flag=1; carry or borrow flag=1; overflow flag=0
IPSR. Exception number: 0b00011 = 3 = HardFault
EPSR. Thumb state bit = 1

$ (gdb) target extended-remote localhost:3333

$ (gdb) monitor reset halt

$ (gdb) set substitute-path /usr/src /Users/ivandyachenko/yet-another-gauge/4-20mA-Loop-Calibrator

$ (gdb) load

$ (gdb) info register
r0             0x0                 0
r1             0x0                 0
r2             0x0                 0
r3             0x0                 0
r4             0x0                 0
r5             0x0                 0
r6             0x0                 0
r7             0x0                 0
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x0                 0
sp             0x0                 0x0
lr             0x0                 0
pc             0x800036c           0x800036c <reset_handler>
xPSR           0x1000000           16777216
msp            0x20008000          0x20008000
psp            0xfffffffc          0xfffffffc
primask        0x0                 0
basepri        0x0                 0
faultmask      0x0                 0
control        0x0                 0
$ (gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /Users/ivandyachenko/yet-another-gauge/4-20mA-Loop-Calibrator/build/4-20mA-Loop-Calibrator.elf
^C
Program received signal SIGINT, Interrupt.
blocking_handler () at ../../cm3/vector.c:104
104		while (1);

$ (gdb) info registers
r0             0x0                 0
r1             0x20                32
r2             0x48000000          1207959552
r3             0x8000560           134219104
r4             0xffffffff          -1
r5             0xffffffff          -1
r6             0xffffffff          -1
r7             0xffffffff          -1
r8             0xffffffff          -1
r9             0xffffffff          -1
r10            0xffffffff          -1
r11            0xffffffff          -1
r12            0xffffffff          -1
sp             0x20007fe0          0x20007fe0
lr             0xfffffff9          -7
pc             0x8000368           0x8000368 <blocking_handler>
xPSR           0x61000003          1627389955
msp            0x20007fe0          0x20007fe0
psp            0xfffffffc          0xfffffffc
primask        0x0                 0
basepri        0x0                 0
faultmask      0x0                 0
control        0x0                 0
$ (gdb) break indicator.c:53
Breakpoint 1 at 0x80000f4: file /usr/src/src/indicator.c, line 53.

$ (gdb) break indicator.c:63
Breakpoint 2 at 0x800010c: file /usr/src/src/indicator.c, line 63.

$ (gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /Users/ivandyachenko/yet-another-gauge/4-20mA-Loop-Calibrator/build/4-20mA-Loop-Calibrator.elf
Note: automatically using hardware breakpoints for read-only addresses.

Breakpoint 1, indicator_new () at /usr/src/src/indicator.c:53
53	  return indicator;

$ (gdb) list
48	  indicator_t *indicator = malloc(sizeof(indicator_t));
49
50	  indicator->pin = LED_GPIO_PIN;
51	  indicator->port = LED_GPIO_PORT;
52
53	  return indicator;
54	}
55
56	void indicator_free(indicator_t *indicator) {
57	  if (indicator != NULL) {

$ (gdb) info locals
indicator = 0x20000090

$ (gdb) p *((indicator_t*) 0x20000090)
$1 = {pin = 32, port = 1207959552}

$ (gdb) continue
Continuing.

Breakpoint 2, indicator_on (indicator=0x20000090) at /usr/src/src/indicator.c:63
63	  gpio_set(indicator->port, indicator->pin);

$ (gdb) list
58	    free(indicator);
59	  }
60	}
61
62	void indicator_on(indicator_t *indicator) {
63	  gpio_set(indicator->port, indicator->pin);
64	}
65
66	void indicator_off(indicator_t *indicator) {
67	  gpio_clear(indicator->port, indicator->pin);

$ (gdb) info args
indicator = 0x20000090

$ (gdb) p *((indicator_t*) 0x20000090)
$2 = {pin = 32, port = 1207959552}

$ (gdb) break gpio_set
Breakpoint 3 at 0x8000148: file ../common/gpio_common_all.c, line 43.

$ (gdb) continue
Continuing.

Breakpoint 3, gpio_set (gpioport=1207959552, gpios=32) at ../common/gpio_common_all.c:43
43		GPIO_BSRR(gpioport) = gpios;

$ (gdb) list
38		     If multiple pins are to be changed, use bitwise OR '|' to separate
39		     them.
40	*/
41	void gpio_set(uint32_t gpioport, uint16_t gpios)
42	{
43		GPIO_BSRR(gpioport) = gpios;
44	}
45
46	/*---------------------------------------------------------------------------*/
47	/** @brief Clear a Group of Pins Atomic

$ (gdb) info args
gpioport = 1207959552
gpios = 32

$ (gdb) step
indicator_on (indicator=0x20000090) at /usr/src/src/indicator.c:64
64	}

$ (gdb) step
main () at /usr/src/src/main.c:34
34	  return 0;

$ (gdb) step
35	}

$ (gdb) step
reset_handler () at ../../cm3/vector.c:62
62	void __attribute__ ((weak)) reset_handler(void)

$ (gdb) step
reset_handler () at ../../cm3/vector.c:96
96		for (fp = &__fini_array_start; fp < &__fini_array_end; fp++) {

$ (gdb) step
^C
Program received signal SIGINT, Interrupt.
blocking_handler () at ../../cm3/vector.c:104
104		while (1);

Implement infinite loop with side-effects:

void infinite_loop(void) {
  while (1)
    asm volatile(""); // this line is considered to have side-effects
}

Add a function call infinite_loop on the end of main function.