post-mortem memory leak search (and analysis) with gdb - c

My goal altogether is to figure out from a post mortem core file, why a specific process is consuming a lot of memory. Is there a summary that I can get somehow? As obvious valgrind is out of the question, because I can't get access to the process live.
First of all getting an output something similar to /proc/"pid"/maps, would help, but
maintenance info sections
(as described here: GDB: Listing all mapped memory regions for a crashed process) in gdb didn't show me heap memory consumption.
info proc map
is an option, as I can get access to machine with the exact same code, but as far as I have seen it is not correct. My process was using 700MB-s, but the maps seen only accounted for some 10 MBs. And I didn't see .so-s there which are visible in
maintenance print statistics
Do you know any other command which might be useful?
I can always instrument the code, but that's no easy. Along with reaching all the allocated data through pointers is like needle in the haystack.
Do you have any ideas?

Postmortem debugging of this sort in gdb is a bit of an art more than a science.
The most important tool for it, in my opinion, is the ability to write scripts that run inside of gdb. The manual will explain it to you. The reason I find this so useful is that it lets you do things like walking data structures and printing out information abou them.
Another possibility for you here is to instrument your version of malloc -- write a new malloc function that saves statistics about what is being allocated so that you can then look at those post mortem. You can, of course, call the original malloc to do the actual memory allocation work.
I'm sorry that I can't give you an obvious and simple answer that will simply yield an immediate fix for you here -- without tools like valgrind this is a very hard job.

If its Linux you dont have to worry about doing stats to your malloc. Use the utility called 'memusage'
for a sample program (sample_mem.c) like below
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(voiid)
{
int i=1000;
char *buff=NULL;
srand(time(NULL));
while(i--)
{
buff = malloc(rand() % 64);
free(buff);
}
return 0;
}
the output of memusage will be
$memusage sample_mem
Memory usage summary: heap total: 31434, heap peak: 63, stack peak: 80
total calls total memory failed calls
malloc| 1000 31434 0
realloc| 0 0 0 (nomove:0, dec:0, free:0)
calloc| 0 0 0
free| 1000 31434
Histogram for block sizes:
0-15 253 25% ==================================================
16-31 253 25% ==================================================
32-47 247 24% ================================================
48-63 247 24% ================================================
but if your writing a malloc wapper then you can make your program coredump after this many number of malloc so that you can get a clue.

You might be able to use a simple tool like log-malloc.c which compiles into a shared library which is LD_PRELOADed before your application and logs all the malloc-type functions to a file. At least it might help narrow down the search in your dump.

Related

How to get the peak dynamicly allocated memory usage of a C/C++ program in Linux system

I would like to know the peak dynamicly allocated memory usage (have already canceled the released memory usage) after running a C/C++ program.
1 (Initial question):
Given a C/C++ program a.out. Can any tool report the peak dynamically allocated memory usage in a way like:
>$ peak-memory ./a.out
Peak dynamically allocated memory size: 12345678 Bytes
2 (Alternative question):
Can I insert a snippit code in the source program such that every time it is executed, it will report the current heap memory usage where I want. This looks like:
int main(){
int *a = (int*) malloc(12);
// some code...
print_heap_usage();
// other code...
}
My research:
I know I can use a wrapper function such as my_malloc and my_free that track the allocated and released memory. But it is not a practical option for other's source code when too many lines of code need to be modified. And prohibitively, this wrapper function can't handle the situation when new and delete are used.
There is one related question Get peak amount of memory used by a C program. But it's only about Windows system and doesn't specifically care about heap memory usage. Some answers indicated the using of getrusage. However, I googled and found it clearly can't tell the heap usage.
Either
Statistics for Memory Allocation with malloc
or
malloc_stats
Note: check the CONFORMING TO sections.
Another gimmick (in terminal):
cat /proc/meminfo
free (from procps package, uses /proc/meminfo, see https://gitlab.com/procps-ng/procps/-/blob/master/proc/sysinfo.c line 698 in function meminfo)

Segmentation fault with ulimit set correctly

I tried to help an OP on this question.
I found out that a code like the one below causes segmentation fault randomly even if the stack is set to 2000 Kbytes.
int main ()
{
int a[510000];
a[509999] = 1;
printf("%d", a[509999]);
return 0;
}
As you can see the array is 510000 x 4 bytes = 2040000 bytes.
The stack is set to 2000 Kbytes (2048000 bytes) using ulimit command:
ulimit -s 2000
ulimit -Ss 2000
Based on those numbers the application has room to store the array, but randomly it return segmentation fault.
Any ideas?
There's a few reasons why you can't do this. There are things that are already using parts of your stack.
main is not the first thing on your stack. There are functions called by the real entry point, dynamic linker, etc. that are before main and they are all probably using some of the stack.
Additionally, there can be things that are usually put on the top of the stack to set up execution. Many systems I know put all the strings in argv and all environment variables on top of the stack (which is why main is not the entry point, there's usually code that runs before main that sets up environment variables and argv for main).
And to top it off a part of the stack can be deliberately wasted to increase the randomness of ASLR if your system does that.
Run you program in the debugger, add a breakpoint at main, look up the value of the stack register and examine the memory above it (remember that most likely your stack grows down unless you're on a weird architecture). I bet you'll find lots of pointers and strings there. I just did this on a linux system and as I suspected all my environment variables were there.
The purpose of resource limits (ulimit) on Unix has never really been to micromanage things down to a byte/microsecond, they are there just to stop your program from going completely crazy and taking down the whole system with it. See them not as red lights and stop signs on a proper road, see them as run-off areas and crash barriers on a racetrack.
If you still wants to access the int location in the array, try to compile the code with out the main..this will not invoke _start
check this discussion enter link description here

Keeping a c program running

After having successfully implemented the karatsuba algorithm, I decided to compare the time needed with the school algorithm. The program needs to test up to 32768 digits. Unfortunately, it stops at 8192 digits(the digits are stored in an array). When running it with gdb I get the output: Programme terminated with SIGKILL, Killed. So obviously I searched through the web and found out that(since I'm on Linux), the kernel automatically killed the program because it consumed too much of resources.
So my question is: Is there a way to keep it running?
Thanks in advance for any response
The most probable cause is memory exhaustion. You can roughly test this hypothesis by running top on the terminal.
If this is the case, valgrind is your friend. Look very carefully at every place you call malloc in your program and ensure that you call free for each array afterwards.
I see a number of things you should do before forcing Linux to keep your program running (if you could do that anyway).
Watch out for memory leaks (see answer of jons34yp)
Once all memory leaks resolved, check the declaration of your
variables, every non used bit but allocated bit is one to many. If a
byte is enough (unsigned char), don't use a short. If a short is
enough, don't use a long. Same for float's and doubles. Also check
eventual structs and unions for unused data.
Also check your algorithm and the way you implement it. e.g. a
sparse matrix can be represented in other ways than waisting entire
array's.
Keep in mind that C compilers use to align data fields. This means
that after for instance, an array of 13 bytes, compilers tend to
align the next bytes on an 32bit or 64bit boundary, leaving you with
unused bytes in between. The same thing can happen within structs.
So check your compilers alignment settings.
I hope this helps to find a solution.
Kind regards,
PB

profiling maximum memory usage in C application - linux

I'm developing C module for php under linux and I'm trying to find a way that could help me profile my code by maximum memory spike (usage).
Using valgrind I can get total memory allocation within the code. But as it is with allocated memory it comes and goes ;). What I need to get is the highest memory usage that appeared during C application run so I could get total overview on memory requirements and have some measurement point for optimization of the code.
Does anyone know any tool/trick/good practice that could help ?
Take a look at Massif: http://valgrind.org/docs/manual/ms-manual.html
Have you checked massif (one of Valgrind's tool)?
this is actually what you are looking for
another possibility would be memusage (one of glibc's utilities, glibc-utils)

Random malloc crash?

I'm trying to read a binary file that has blocks starting with an identifier (like a 3DS file). I loop through the file and using a switch the program determines what identifier a block has and then reads the data into the file struct. Sometimes I need to use malloc to allocate memory for dynamic sized data. While reading, the switch often goes through the same case wherin memory is allocated, but at a specific point in the file it crashes on that same malloc. The file that I want to read is about 1MB. But when I try the program with another file of about 10kB and the same structure, it reads it succesfully.
What could be causing this problem?
The error code that I get when debugging is:
Heap corruption detected at 0441F080
HEAP[prog.exe]: HEAP: Free Heap block 441f078 modified at 441f088 after it was freed
Also when I execute it in debug mode, for some reason I can read more data from the file. The program lives longer before it crashes.
Here is the code piece where it crashes:
switch (id) {
case 0x62:
case 0x63:
// ...
{
char n_vertices = id - 0x60 + 1;// just how I calculate the n_vertices from the block ID
fread(&mem.blocks[i].data.attr_6n.height, 2, 1, f);
mem.blocks[i].data.attr_6n.vertices = malloc(2 * n_vertices);// crash
for (short k = 0; k < n_vertices; k++) {
fread(&mem.blocks[i].data.attr_6n.vertices[k], 2, 1, f);// read shorts
}
}
break;
// ...
}
You probably have a corrupt heap. This could be caused by invalid deallocations (deallocating unowned or already free memory), or by some random chunk of code writing outside its memory area into a place that happens to hold the heap bookeeping data structures. This most likely will be a piece of code that has nothing whatsoever to do with that dynamically allocated memory.
Tracking down bugs like this is a real bear. They tend to appear long after the offending code has executed, and they have an annoying tendency to turn into heisenbugs (bugs that move or go away when you attempt to debug them).
My suggestion for approaching debugging would be to try to comment out portions of your code and see what causes the problem to go away. That isn't foolproof, as you could just end up moving the out-of-bounds write to somewhere else.
Looking over the code you just posted, one thing I would highly suggest you do is verify that your malloc specified enough memory to hold all the data you are attempting to load into it. It looks to me like you are assuming 2 bytes for each vertex. That seems a bit suspicious to me. I don't know your code, but 4 or 8 would be much more common element sizes to see there. Regardless, industry practice is to use sizeof() on the target type to help ensure you have it right.
Another option, if that debugger message of yours can show you where it is happening, would be to put a debugger watch point there (or write some watching code...or manually dump and inspect the area) when stepping in the debugger to try to figure out which is the offending line of code.
Good luck. I hate these bugs.
Most likely the heap gets corrupted somehow, malloc is crashing e.g. trying to traverse a corrupted linked list of free blocks (or a similar structure, I'm not exactly sure what is used in modern heap allocators these days).
Make sure your code is not writing past the end of an allocated block.
You need to run this in a memory debugger like valgrind. Since it looks like you're on windows, see the following: Is there a good Valgrind substitute for Windows?

Resources