How Backtrace works on Linux x86_64? - c

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.

Related

Can we do this with GCC's inline functions?

As far as I know inline functions are code substituted in the caller, which means that any code written in an inline function lives in the last function's stack frame. I happen to be in a situation where I need to allocate memory dynamically without using malloc. Is there a way, then, for me to allocate a variable-length array in an inline function, and have it persist when the function terminates---you know, since the stack isn't really unwinding.
Thanks!
EDIT:
What I have is a function called in signal handler context, activated by sigpoll. It attempts to read data from a tcp socket. The data it reads is organised into data structures we came up with; artificial "packets", if you will. There is no telling how much data is in the buffer, where the "packet" boundaries are, etc. It's called by a signal handler, so we can't use any dynamic memory allocators.
Hmm. This seems to be another aspect of what you want. Call all the alloca function to allocate stack memory. alloca()- allocated memory goes away when the function terminates. It returns a pointer
See this for further information. Also note that using alloca may cause some other issues, so it is not perfect.
http://man7.org/linux/man-pages/man3/alloca.3.html

Runtime Memory allocation on stack

I want to know about runtime memory allocation on stack area and how its different from runtime memory allocation on Heap area.
I know how memory get allocated by using library function.
#include<alloca.h> void *alloca(size_t size); //(for runtime memory on stack)
#include<stdlib.h> void *malloc(size_t size); //(for run time memory on heap)
I also know that if we are using alloca function we don't need to free that memory explicitly because it is associated with stack, its get freed automatically.
I want to know which system calls are associated with alloc and malloc and how they works in both.
In short they usually don't use system calls, unless running out of available memory.
The bahavior is different for either, so I explain differently.
malloc
Let's say initially your program has 1MB (for example) available memory for allocation. malloc is a (standard) library function that takes this 1MB, looks at the memory you want to allocate, cut a part of the 1MB out and give it to you. For book-keeping, it keeps a linked-list of unallocated memories. The free function then adds the block being freed back to the free list, effectively freeing the memory (even though the OS still doesn't get any of it back, unless free decides that you have way too much memory and actually give it back to the OS).
Only when you run out of your 1MB does malloc actually ask the operating system for more memory. The system call itself is platform dependent. You can take a look at this answer for example.
alloca
This is not a standard function, and it could be implemented in various ways, none of which probably ever call any system functions (unless they are nice enough to increase your stack size, but you never know).
What alloca does (or equivalently the (C99) standard variable length arrays (VLA) do) is to increase the stack frame of the current function by adjusting proper registers (for example esp in x86). Any variable that happens to be on the same stack frame but located after the variable length array (or allocaed memory) would then be addressed by ebp + size_of_vla + constant instead of the good old simple ebp + constant.
Since the stack pointer is recovered to the frame of the previous function upon function return (or generally on exit of any {} block), any stack memory allocated would be automatically released.
The alloca() function is typically implemented by the compiler vendor, and doesn't have to be a "system call" at all.
Since all it needs to do is allocate space on the local stack frame, it can be implemented very simply and thus be incredibly fast when compared to malloc().
The Linux manual page for it says:
The inlined code often consists of a single instruction adjusting the stack pointer, and does not check for stack overflow.
Also, I'm not sure you realize that the memory gets deallocated "automatically" when the function that called alloca() exits. This is very important, you can't use alloca() to do long-lived allocations.
The alloca function is, according to its manpage a function that is inlined and will be specially treated by the compiler and expanded (at least for gcc).
The behavior is implementation-defined and as such, should not be used, for you cannot gurantee it to work the same way always.

What is the need for having "nmem" and "size" parameters in C functions? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
c difference between malloc and calloc
Why does calloc require two parameters and malloc just one?
I've noticed this with many C functions calls particularly ones that deal with memory or file operations, but not all of them use both parameters. For instance malloc is passed one parameter, the size in bytes of the memory space needed. Calloc on the other hand is passed two parameters, the size in bytes of an element and the number of elements (size and nmem). There are other functions that use these size and nmem parameters as well.
Essentially the calloc call would allocate the same amount of memory as calling malloc(nmemsize) so all that's really happening is the asterisk () is replaced with a comma (,). At least this is all I can tell from the higher level that I am working at. I don't see a difference from calling calloc(1, nmemsize), calloc(nmemsize, 1), or calloc(nmem, size).
Is there something actually happening at a lower level that makes calling for instance calloc(1, nmem*size) fundamentally different from calloc(nmem, size)?
Edit: I know the functional difference between calloc and malloc. I'm interested in why there are differences in the parameters. There are other functions that use 2 size parameters for the total size (fread, fwrite, etc). I'm not concerned with the specific functions but rather why there are two parameters for the total size used in the function when essentially the total size becomes the two parameters multiplied together. I find most of the time when I use these functions I use the size that I need in the "size" parameter and a '1' for the "nmem" (sometimes "count" etc.) parameter.
In a comment to the question, I wrote that calloc() allows better memory alignment for platforms where it matters. I haven't been able to find anything to support that (yet). I am pretty sure it was a feature of the VMS/VAXC compiler, but source for that is scarce.
However, I did find that calloc() and alloc() appeared at the same time, with the release of Unix V6 in May 1975. In V5, released 11 months earlier, neither function is present; the kernel and runtime library (and assembler and C compiler) were written in assembly.
In the V6 release, calloc is implemented as the four line source code module:
calloc(n, s)
{
return(alloc(n*s));
}
calloc() does not clear the allocated memory; see alloc(), and there was no man page for calloc() in V6; however the man page for alloc():
DESCRIPTION
Alloc and free provide a simple general-purpose core management package.
Alloc is given a size in bytes; it returns a pointer to an area at least that size which
is even and hence can hold an object of any type. The argument to free
is a pointer to an area previously allocated by alloc; this space is made available for further allocation.
Needless to say, grave disorder will result if the space
assigned by alloc is overrun or if some random number is handed to free.
The routine uses a first-fit algorithm which coalesces blocks being freed with other
blocks already free. It calls sbrk (see "break (II))"
to get more core from the system when there is no suitable space already free.
DIAGNOSTICS
Returns -1 if there is no available core.
BUGS
Allocated memory contains garbage instead of being cleared.
Not even NULL is returned in the case of memory exhaustion!
calloc() first formally appears in UNIX V7, January 1979, along with several other improvements:
calloc() clears the memory returned.
alloc() was renamed to malloc()
realloc() appeared
in the case of memory exhaustion or a heap error, the functions "return a null pointer (0)"
Is there something actually happening at a lower level that makes calling for instance calloc(1, nmem*size) fundamentally different from calloc(nmem, size)?
This attempt to explain things is purely dependent from the libc implementation - and therefore left at the appreciation of a specific libc author:
Since calloc() is zeroing memory, the rationale might have been that it could (potentially) waste some more cycles at doing a mult.
In contrast, malloc() is given a chance to use a precalculated value, potentially reducing the overhead in a call that migh be simpler to satisfy.
Don't forget that C was designed at a time when each CPU cycle was costing a lot - hence a very lean design as compared to many other 'higher-level' languages.
This question could probably be better answered by the author of C Dennis Ritchie.

Which C standard library functions use malloc under the hood

I want to know which C standard library functions use malloc and free under the hood. It looked to me as if printf would be using malloc, but when I tested a program with valgrind, I noticed that printf calls didn't allocate any memory using malloc. How come? How does it manage the memory then?
Usually, the only routines in the C99 standard that might use malloc() are the standard I/O functions (in <stdio.h> where the file structure and the buffer used by it is often allocated as if by malloc(). Some of the locale handling may use dynamic memory. All the other routines have no need for dynamic memory allocation in general.
Now, is any of that formally documented? No, I don't think it is. There is no blanket restriction 'the functions in the library shall not use malloc()'. (There are, however, restrictions on other functions - such as strtok() and srand() and rand(); they may not be used by the implementation, and the implementation may not use any of the other functions that may return a pointer to a static memory location.) However, one of the reasons why the extremely useful strdup() function is not in the standard C library is (reportedly) because it does memory allocation. It also isn't completely clear whether this was a factor in the routines such as asprintf() and vasprintf() in TR 24731-2 not making it into C1x, but it could have been a factor.
The standard doesn't place any requirements on the implementation, AFAIK.
I don't know exactly how printf is implemented, but of the top of my head, I can't think of a reason why it would need to dynamically allocate memory. You could always look at the source for your platform.
It depends on which libc you are using. There should be no restriction on the C spec and up to the implementation.
For instance, newlib's printf usually done with using memory on stack frame, but when it really needs to, it calls an internal function _malloc_r() directly.
I have not used valgrind, I'm not sure if it can detect use of _malloc_r().
Neither the C nor the POSIX standard force implementors to make use of malloc(), so there's no general answer to your question.
However, every sane standard library implementation that uses malloc() in one of its functions will set errno to ENOMEM if malloc() fails. Hence, you can derive from the documentation whether a library function uses malloc() or not. Point in case: on my system, mmap() may use malloc(), since mmap() may set errno to ENOMEM.
That having said, using valgrind is a poor way to find out whether a particular function calls malloc() or not. Consider the following piece of code:
void foo(int x)
{
if (!x) malloc(1);
}
If you call this function with an argument other than 0, valgrind won't notice that it may actually call malloc(). Think of valgrind as a virtual machine (since that's what it is): it doesn't look at your code, it only sees what the machine would actually execute.
printf doesn't need to form the entire output string in one shot, it can send it to output piece by piece, and when it encounters a format specifier, it can output that piece of data as it is formed, and continue on with the rest of the string.
At most it would need a locally defined array of characters (on the stack) large enough to hold the largest integer or floating point number it can handle, which isn't very large.

Is there a function to invoke a stack dump in 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.

Resources