-1

I was writing some logging logic and wanted to make some indentations. The easiest way to understand whether any function call was present or if some function has finished is to look at the current address of the stack/frame. Let's suppose that stack grows upside down. Then if the stack address in the log() call is smaller than during the previous call, we can increase the indent since some function call was present. I know there are functions like backtrace() that know how to dump it, or you can use some assembly. However, I remember reading about external variables that can be used to retrieve this information. Can someone name these variables or give a reference where I can find them (as far as I remember, it was in some computer systems book like "Computer Systems: A Programmer's Perspective "). Otherwise, what is the most convenient/fast way of getting this information?

Update: I have accidentally found the link I was referring to - Print out value of stack pointer
TLDR: There is no portable way to do what I have described...

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • I think you want to look at the current RIP (program counter), not RSP (stack pointer), if you want to know what function is *currently* executing. `log()` in `libm` is probably a leaf function, so it won't call other functions. Or are you writing your own function with the same name as a math library function that does something unrelated? – Peter Cordes Sep 15 '18 at 18:30
  • 'log()' is just my macros/function that is supposed to look at frame address (within which it is called) and compare it with previous, therefore RIP has no interest for me – Volodymyr Huti Sep 15 '18 at 18:32
  • Under `gcc`, you can use the special functions: `__builtin_return_address`, `__builtin_frame_address`, etc. See the info page for `gcc` for details – Craig Estey Sep 15 '18 at 18:34
  • 1
    Like @R said this is a highly specialized area. GCC provides Backtrace API to walk stacks. See [34.1 Backtraces](https://www.gnu.org/software/libc/manual/html_node/Backtraces.html) in the GCC manual. I don't recall a similar API for MSVC and Windows. John Robbin's [Debugging Applications](https://www.amazon.com/dp/0735608865) book may have some suggestions, but I don't have it handy. it is probably part of the Debugging Tools SDK. – jww Sep 15 '18 at 18:45
  • Once you enable optimization with any modern compiler, you are going to be in for some confusion.. – Jesper Juhl Sep 15 '18 at 18:46
  • 1
    Possible duplicate of [How to automatically generate a stacktrace when my program crashes](https://stackoverflow.com/q/77005/608639) – jww Sep 15 '18 at 18:56
  • Probably not a duplicate, as the OP is looking to size an indent. But certainly that answer gives a route to solving the OP's problem. – lockcmpxchg8b Sep 15 '18 at 19:03

1 Answers1

3

This method is highly nonportable and will break under various transformations, but if you're just using it for debug logging it might be suitable.

The easiest way to get something resembling the current stack frame address is just take the address of any automatic-storage (local, non-static) variable. If you want a baseline to compare it against, save the address of some local in main or similar to a global variable. If your program is or might be multi-threaded, use a thread-local variable for this if needed.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • Or for a baseline, pass an extra function arg of type `const char*` or `const void*`. Recursive calls can pass on the arg to use the same reference, but other calls can pass the address of a local. static storage is probably more efficient, though, even if it does have to be thread-local. – Peter Cordes Sep 15 '18 at 18:33