It’s a compiler bug!!! Yes!! It is!! Seriously, it is!!!
Well… is it? Let’s have a look. What is going on with my RISCV debugging issue.
So, last time, I mentioned, a binary built with GCC 8 could be debugged fine with GDB,
however, building the same code with GCC 12 gave issues with GDB disagreeing about
the stack layout.
Next, I created a minimal test case, to be built with GCC12. Minimal code, including
the startup code. Disable all interrupts, no vector table, just to the minimal to boot.
And then, the problem was gone… but why? What was the difference. Next, I pulled the
same code through by build system, and there was the problem.
So… it seemed… it was something in my build system creating the issue.
The problem has to be in the parameters passed to the compiler while building.
I have traced the problem down to the generation of assembly listing when compiling a C file.
This is a parameter passed to the assembler, so technically, this ain’t a compiler bug.
See https://github.com/a-v-s/riscv_gcc_debug_issue for an example how to reproduce these results.
I haven’t tried your example, but it’s an interesting premise.
As a meta note, if you ever expect to read the .s files or single stepi in the debugger or such, you will probably find -O1 preferable to -O0. It’s counterintuitive, but 0 just does the dumbest possible thing and almost always results in a ton of spilling and general dumbness. I1 is usually closer to what a human would “speed write” (not being excessively clever) to do a mostly rote translation to assembler. As a bonus, it’s almost always smaller so it’s less code to look at or upload.
It’s not relative to you issue, so don’t let it be a distraction, but just a general tip to the audience for debugging or learning RISC-V (or any other) assembler.
Thank you for the posts. You’re now in my RSS feed!
I might have a look at how code generate with O1 behaves in the debugger. I must admit I’ve never looked at it much. I usually went debugging with O0, and releasing in either O2 or Os, depending whether size is an issue.
I’ll have a look how O1 code behaves in the debugger. Does it hit my breakpoints, and not jump all over the place like usual optimised code does?
I’m looking into the 32F103 clones again, and one of the upcoming things will be running some benchmarks on them. And when doing this, I am also planning to look at the effect of optimisation flags.