Is there a function to invoke a stack dump in C? - c

Can someone please provide an implementation of a C function that gets invoked to dump the current stack? It's for a x86 linux system. It can be invoked in 2 ways: explicitly by another function, or after a crash (probably as a trap/int handler). The output can be either to the screen or to a file, as indicated by a parameter (handle). A clear explanation/comments of how the stack is unwound would obviously be very helpful. Thank you.

The documentation for the backtrace() function is in the GNU LIBC MANUAL.

following on Adam's answer, the source code that shows how to perform the actual stack backtracing is in gnu libc's backtrace(), under /libc/debug/backtrace.c - not sure if the full link below will be accepted by stackoverflow's html filters...
http://cvs.savannah.gnu.org/viewvc/*checkout*/libc/debug/backtrace.c?root=libc&revision=1.1.2.1&content-type=text%2Fplain

When function calls are nested, the stack grows downwards and builds a chain of stack frames. At any given point in a program it is theoretically possible to backtrace the sequence of stack frames to the original calling point. The backtrace() function navigates the stack frames from the calling point to the beginning of the program and provides an array of return addresses. The implementation of backtrace() in the glibc library contains platform-specific code for each platform.
In the case of an x86 platform, the contents of the ebp (base pointer) and esp (stack pointer) CPU registers, which hold the address of the current stack frame and of the stack pointer for any given function, are used to follow the chain of pointers and move up to the initial stack frame. This allows the sequence of return addresses to be gathered to build the backtrace.
If you would like to know more information on how backtrace() works and how to use it, I would recommend reading Stack Backtracing Inside Your Program (LINUX Journal).
Since you mentioned executing a backtrace from a signal handler for an x86 platform, I would like to add to Adam's answer and direct you to my response to the question he linked to for details on how to ensure a backtrace from a signal handler points to the actual location of the fault.

Related

GDB: Find stack memory address where return address of a function is stored?

I'm working on producing a buffer overflow on my Raspberry Pi (ASLR disabled).
I have a program, which has a main function, a vulnerable function and a function which should not be called, the evil function.
My main function calls the vulnerable function at some point, but the evil function obviously never gets called. I need to make sure it does, using a buffer overflow.
So what I have got so far is the return address of the vulnerable function in the main function, which I want to overwrite with the starting address of the evil function. I think this is correct approach.
However I wasn't able to figure out how I examine the memory in gdb in such a way so that I find at what stack address the return address is stored. There is an example available, which inputs a string of characters through gdb while the program is running, then they look up the memory around the stackpointer and somehow that is where the return address is stored. This seems rather weird to me, since how could they know that their input gets stored just a couple addresses away from the desperately wanted return address.
My question is if I can 'search' the stack for my return address using gdb.
The Raspberry Pi is running an ARM microcontroller, so you should read more about the ARM architecture and calling convention.
You should read more about ARM registers, especially the stack pointer (abbreviated SP) as well as the link register (abbreviated LR: this is where the return address of a function is stored). See for instance this question for a good explanation.
To visually inspect the values of those registers with gdb, you can use the instruction info registers, (also work if you type i r). See the doc for more details.

Implementing stack backtrace without using ebp

How a stack backtrace can be implemented when the compiler is explicitly told not to use ebp as stack frame pointer?
The answer to this was only ever in comments on the accepted answer on What is the purpose of the EBP frame pointer register?.
Modern debuggers can do stack backtraces even in code compiled with -fomit-frame-pointer. That setting is the default in recent gcc.
gcc puts the necessary stack-unwind info into a .eh_frame_hdr section. See this blog post for more details. It's used for runtime exceptions, too. You'll find it (with objdump -h) in most binaries on a Linux system. It's about 16k for /bin/bash, vs. 572B for GNU /bin/true, 108k for ffmpeg.
There is a gcc option to disable generating it, but it's a "normal" data section, not a debug section that strip removes by default. Otherwise you couldn't backtrace through a library function that didn't have debug symbols. That section may be bigger than the push/mov/pop instructions it replaces, but it has near zero runtime cost (e.g. uop cache).
I think the info stored in that section is a mapping from return-address to size of stack frame. Since every call instruction pushes the address of the following instruction onto the stack, you can identify the parent caller from that address. Instead of pushing ebp to make a linked list of stack frames on the stack, the offset to the next return address is stored in the .eh_frame_hdr section, so it can be used if needed by code that needs to backtrace.

How to get the size and the starting address of the stack per thread in posix C?

How can I get the size and the starting address of the stack per thread in posix C? Or if there's no standard posix way to do this, at least in Linux with gcc.
Some programs such as the Boehm-gc should do this somehow, but I'm now quite confused reading their code. Can you give me some function names?
The "clean" but non-portable way to do this is to use the pthread_getattr_np (Linux/glibc, etc.) or similar function to obtain an attributes object for the thread in question, then pthread_attr_getstack to obtain the stack base/size. There is no portable way to do this, however, and there's essentially nothing portable you could do with the results anyway.
For the single-threaded case, just take the address of a local variable in the original and current frames.
Any address that lies between the current function's stack and main's stack must be in the stack.
Note that this does not apply to variables located directly. You may have to disable inlining for a handful of functions.

Initialise Stack pointer on ATtiny2313

I am programming an ATtiny2313 using avrdude and a makefile. I believe the stack pointer is not properly initialised, since when I call a function, the program appears to freeze. I found the following assembly code:
.include "tn2313def.inc"
ldi r16, low(RAMEND) ; Main program start
out SPL,r16 ;Set Stack Pointer to top of RAM
which I think might work, but I don't know how I can incorporate it into the c code that I created. ie. do I need to include a special header file or somehow denote that it is assembly and not c. I am relatively new to programming and I would appreciate any help either as to how to implement this code properly or another way of making my current c code initialise a stack pointer.
Thank you in advance.
Stephen
It really depends on how you've got your makefile configured as to whether the stack pointer will be initialised. If you're using gcc and the normal compile and link options, the linker ensures that some startup code crtX.o is also included in your executable. The linker automatically chooses the correct crtX.o file for your processor and compile options.
Amongst other things, the code in the crtX.o files will clear the bss segment to be all zeros as required by the C standard, configure your stack pointer and provide interrupt vectors in the correct location for those which have not been overridden.
Remember that the ATTiny2313 only has 128 bytes of SRAM. This area must be big enough for any initialised data you have in your program and the stack. Just the process of calling a simple function will use up quite a number of bytes of RAM to save the registers on the stack before calling the function.
So, I'd suggest to do these things:
Use the standard makefile if one is provided by your compiler, it will ensure that the standard startup code is included and that the stack/RAM is set up correctly before main() is called.
Turn on the linker map and symbol file output and verify that you actually have some space free that can be used for the stack.
The Atmel IDE has a reasonable simulator, so try running your code in the simulator. You'll be able to watch stack usage as you are calling the function and location any odd behaviour.
You may just happen to have a stack overflow (which is why you came to stackoverflow.com right?

How Backtrace works on Linux x86_64?

i have several questions:
int backtrace(void **buffer, int size);
Here buffer is array of pointers. and the array elements on returns points to each frame of stack in return. So, backtrace() internally calls malloc() number of times as that of number of frames? why this is for?
the above allocated memory is not freed() from backtrace(), So, who release this memory?
is there any way, to avoid malloc() from inside backtrace()?
where can i find backtrace() source code?
how can i write code to backtrace in assembly?
Please read the manual page for backtrace a bit more carefully. You seem to be mistaken about some of the fundamentals:
No, array is your buffer of pointers, which are filled-in by backtrace() to point at the stack frames. No calls to malloc() are made.
You, since it's your memory.
Not applicable, backtrace() does not call malloc().
It's part of GNU libc. Here is one part of the implementation.
Probably by copying the stack pointer and manually walking the stack.
You seem to confuse backtrace() with backtrace_symbols(), the latter involves memory allocations.
To read out the current backtrace up to a maximum of 64 levels, just do:
void *stack[64];
const int depth = backtrace(stack, sizeof stack / sizeof *stack);
Apparently, the GNU backtrace() function calls malloc() once -- and then never calls it again. If one examines the source, one sees that backtrace() invokes several "dl" functions to unwind the stack, and one of those must be calling malloc(). I agree that malloc() is being called. I get around the problem when I load my heapmanager hooks by calling backtrace() once during the initialization phase so I can avoid a recursive call to the hooked malloc() function as I attempt to develop the list of calling sequences in my software associated with the heap.

Resources