Getting the call stack in C
WPB (1391) 352 posts |
Is there a way using Norcroft C to access the call stack for debugging purposes? I.e. can I get a list of functions called that have got me to where I am now? |
David J. Ruck (33) 1636 posts |
Yes, more details to follow. |
David J. Ruck (33) 1636 posts |
Tried to post, but forum formatting has screwed it so will have to try again when I get back. |
WPB (1391) 352 posts |
Thanks, David – appreciate your efforts! ;) |
David J. Ruck (33) 1636 posts |
Here’s some code from ARMalyser, which I’m sure I got off someone else. Link with backtrace.c and registers.s In your main file include signal.h kernel.h, backtrace.h and put in the following code:-
Or you could call the Backtrace function directly, from anywhere. Give an argument of SIGINT to stop, zero to continue.
|
David J. Ruck (33) 1636 posts |
backtrace.h
|
David J. Ruck (33) 1636 posts |
backtrace.c
|
David J. Ruck (33) 1636 posts |
registers.s
|
David J. Ruck (33) 1636 posts |
I don’t know what is up with the formatting on here, but if you want usable files, drop me an email. [Edit] Grrr. Trying lots of combinations of <pre><code>arrrh</code></pre> and it was messing up in many varied ways, until I discovered the one which worked had a blank line between the filename and the code block. |
David J. Ruck (33) 1636 posts |
That code is over 20 years old, so I’m not sure stuff like the ROM location is valid anymore. |
WPB (1391) 352 posts |
David, thanks so much for posting this. I need to study it and work out how it works! |
Stuart Swales (8827) 1357 posts |
Surely needs a ptr-=4 as ptr isn’t a pointer in this code! Otherwise unaligned accesses will occur. Doesn’t fault on old systems and will crawl back bytewise to the procedure name if present, but some newer systems with the appropriate alignment options set will barf right when you don’t want them to in the middle of your attempt at debugging. |
Charles Ferguson (8243) 427 posts |
From a question on usenet some years ago, I published this as an example of how Doom traverses the backtrace when it reports errors (see the function I_Error): https://usenet.gerph.org/SCL-Backtrace/ These days I rarely bother with capturing the backtrace within an application because the standard reporting used by the SCL will give sufficient information to explain what’s going on if an exception occurs, and will be captured in a diagnostic dump. On the other hand, it’s handy for those rare times when you want to inspect the state of the system at a given call. But it’s still a lot easier to just call the SWI to dump the entire state in those cases. Of course in Pyromaniac the same style of strack traversal is also done on any trace triggers. Druck’s code looks a bit more complete, in any case. |
Stuart Swales (8827) 1357 posts |
The adventurous could burn themselves a SharedCLibrary with procedure names. In the RISCOS_Lib Makefile, the build rules which map c source files to the rm_o object files used to build the softload SharedCLibrary can be modified thus:
where [Edit: Ignore this bit: I prefer the |
Colin Ferris (399) 1818 posts |
Back in the times of the troubles – there was a softload CLib module – was that done all in ‘C’ ? |
Stuart Swales (8827) 1357 posts |
@Colin: Take a peek in the hard disc image’s !System – there’s still a soft-loadable CLib! However, as that has to work on any system, it’s not as optimised as the one found in your RISC OS 5 ROM which has been tuned for use with that particular system, using newer ARM instructions etc. There has always been a good wodge of assembler in the C library. If it were all written in C, you’d be disappointed with its performance! The idea being that folk who know how to tune code for that architecture do it once so that everyone benefits, rather than you having to worry too much. That said, it took a couple of years BITD to put a decent memcpy() into the C library to replace the generic one written in C. For shunting non-byte-aligned data around, ISTR about a factor of 13 was involved, so PipeDream used a homebrew implementation for years. In fact, until I stopped 26-bit builds, as the SharedCLibrary needed to provide decent memcpy() didn’t work on RISC OS 2. |
WPB (1391) 352 posts |
Thanks, Charles, for the additional code sample, and everyone else for their various input. |