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.