I’m going to look into some more details regarding the debugging issues I am experiencing with a GCC12 toolchain that do not appear in a GCC8 toolchain on RISCV microcontrollers.
I’m loading the binary, set a breakpoint, run the code until the breakpoint hits, and request a backtrace.
Compiled with the MounRiver GCC8 toolchain I get
(gdb) target extended-remote localhost:3333 Remote debugging using localhost:3333 warning: No executable has been specified and target does not support determining executable automatically. Try using the "file" command. 0x00005bbc in ?? () (gdb) file mounriver-studio-toolchain-riscv/i2c_demo.elf A program is being debugged already. Are you sure you want to change the file? (y or n) y Reading symbols from mounriver-studio-toolchain-riscv/i2c_demo.elf... (gdb) load mounriver-studio-toolchain-riscv/i2c_demo.elf Loading section .vtor, size 0x200 lma 0x0 Loading section .text, size 0xa574 lma 0x200 Loading section .sdata2.APBPrescTable, size 0x8 lma 0xa774 Loading section .sdata2.u8x8_d_ssd1306_128x64_noname_powersave0_seq, size 0x5 lma 0xa77c Loading section .sdata2.u8x8_d_ssd1306_128x64_noname_powersave1_seq, size 0x5 lma 0xa784 Loading section .sdata2.u8x8_d_ssd1306_128x64_noname_flip0_seq, size 0x7 lma 0xa78c Loading section .sdata2.u8x8_d_ssd1306_128x64_noname_flip1_seq, size 0x7 lma 0xa794 Loading section .data, size 0x84 lma 0xa79c Loading section .sdata.bshal_delay_cycles, size 0x4 lma 0xa820 Loading section .sdata.SystemCoreClock, size 0x4 lma 0xa824 Loading section .sdata._impure_ptr, size 0x4 lma 0xa828 Start address 0x00004fe0, load size 43044 Transfer rate: 6 KB/sec, 3311 bytes/write. (gdb) break u8g2_font_decode_len Breakpoint 1 at 0x5b88: file ../../..//ext/u8g2/csrc/u8g2_font.c, line 400. Note: automatically using hardware breakpoints for read-only addresses. (gdb) continue Continuing. Breakpoint 1, u8g2_font_decode_len (u8g2=0x20000014, len=0 '\000', is_foreground=0 '\000') at ../../..//ext/u8g2/csrc/u8g2_font.c:400 400 u8g2_font_decode_t *decode = &(u8g2->font_decode); (gdb) bt #0 u8g2_font_decode_len (u8g2=0x20000014 , len=0 '\000', is_foreground=0 '\000') at ../../..//ext/u8g2/csrc/u8g2_font.c:400 #1 0x00006078 in u8g2_font_decode_glyph (u8g2=0x20000014 , glyph_data=0x9f6f "\263b\263bkJ\n4b73\310 \225\021K\t4b\023U\222\251\063L\f4b\223A\006\031d\220\301\bM\t4b\023\307", ) at ../../..//ext/u8g2/csrc/u8g2_font.c:605 #2 0x000062aa in u8g2_font_draw_glyph (u8g2=0x20000014 , x=15 '\017', y=16 '\020', encoding=73) at ../../..//ext/u8g2/csrc/u8g2_font.c:724 #3 0x0000638c in u8g2_DrawGlyph (u8g2=0x20000014 , x=15 '\017', y=16 '\020', encoding=73) at ../../..//ext/u8g2/csrc/u8g2_font.c:789 #4 0x00006418 in u8g2_draw_string (u8g2=0x20000014 , x=15 '\017', y=16 '\020', str=0x9ae0 "²C DEMO") at ../../..//ext/u8g2/csrc/u8g2_font.c:807 #5 0x000064ec in u8g2_DrawUTF8 (u8g2=0x20000014 , x=0 '\000', y=16 '\020', str=0x9adc " I²C DEMO") at ../../..//ext/u8g2/csrc/u8g2_font.c:861 #6 0x00001074 in print (str=0x9adc " I²C DEMO", line=1) at dis2.c:50 #7 0x00000366 in main () at main.c:174
Compiled with the xPack GCC12 toolchain I get
(gdb) target extended-remote localhost:3333 Remote debugging using localhost:3333 warning: No executable has been specified and target does not support determining executable automatically. Try using the "file" command. 0x00005b88 in ?? () (gdb) file riscv-none-elf/i2c_demo.elf A program is being debugged already. Are you sure you want to change the file? (y or n) y Reading symbols from riscv-none-elf/i2c_demo.elf... (gdb) load riscv-none-elf/i2c_demo.elf Loading section .vtor, size 0x200 lma 0x0 Loading section .text, size 0xa5a0 lma 0x200 Loading section .srodata.APBPrescTable, size 0x8 lma 0xa7a0 Loading section .srodata.u8x8_d_ssd1306_128x64_noname_powersave0_seq, size 0x5 lma 0xa7a8 Loading section .srodata.u8x8_d_ssd1306_128x64_noname_powersave1_seq, size 0x5 lma 0xa7b0 Loading section .srodata.u8x8_d_ssd1306_128x64_noname_flip0_seq, size 0x7 lma 0xa7b8 Loading section .srodata.u8x8_d_ssd1306_128x64_noname_flip1_seq, size 0x7 lma 0xa7c0 Loading section .data, size 0x84 lma 0xa7c8 Loading section .sdata.bshal_delay_cycles, size 0x4 lma 0xa84c Loading section .sdata.SystemCoreClock, size 0x4 lma 0xa850 Loading section .sdata._impure_ptr, size 0x4 lma 0xa854 Start address 0x0000500c, load size 43088 Transfer rate: 6 KB/sec, 3314 bytes/write. (gdb) break u8g2_font_decode_len Breakpoint 1 at 0x5bbc: file ../../..//ext/u8g2/csrc/u8g2_font.c, line 400. Note: automatically using hardware breakpoints for read-only addresses. (gdb) continue Continuing. Breakpoint 1, u8g2_font_decode_len (u8g2=0x2000006c, len=4 '\004', is_foreground=0 '\000') at ../../..//ext/u8g2/csrc/u8g2_font.c:400 400 u8g2_font_decode_t *decode = &(u8g2->font_decode); (gdb) bt #0 u8g2_font_decode_len (u8g2=0x2000006c , len=4 '\004', is_foreground=0 '\000') at ../../..//ext/u8g2/csrc/u8g2_font.c:400 #1 0x000060ba in u8g2_font_decode_glyph (u8g2=0x2000006c , glyph_data=0x4004db0 '\377' ...) at ../../..//ext/u8g2/csrc/u8g2_font.c:605 Backtrace stopped: frame did not save the PC (gdb)
On the binary compiled with the GCC8 toolchain, the result is as expected. However, on the GCC12 toolchain, GDB behaves as if the stack is corrupted. However, the program appears to be operational. So it feels like GDB is interpreting it incorrectly for some reason.
One observation, looking at these outputs then loading the binary, it seems some section names are different. .sdata2
vs .srodata
. Would my problem be in my linker file? But if anything would be wrong there, it code shouldn’t be running. This problem appears to be limited to debugging with gdb. So, why?
Now, having a look at the ELF files:
[andre@mortar tests]$ readelf -A mounriver-studio-toolchain-riscv/i2c_demo.elf [andre@mortar tests]$ readelf -A riscv-none-elf/i2c_demo.elf Attribute Section: riscv File Attributes Tag_RISCV_stack_align: 16-bytes Tag_RISCV_arch: "rv32i2p1_m2p0_a2p1_c2p0" Tag_RISCV_priv_spec: 1 Tag_RISCV_priv_spec_minor: 11
We see the GCC12 binary got architecture specific attributes, which include stack alignment information. This is missing from the binary produced with GCC8. Could this explain the difference in behaviour?
I’ve uploaded the binaries. These should be able to run on either GigaDevice GD32VF103 or WinChipHead CH32V103. These are linked at 0x0. This will flash with the RISCV fork of OpenOCD. I’ve noticed OpenOCD has mainstreamed GD32VF103 support, but required to be linked at 0x08000000 instead (like any STM32), so if you want to try these, use the forked version.