I got a core from g_ascii_strdown() which said it got error while doing malloc() and it crashed. So if the process hit out-of-memory case, is there a way to find out, from core and gdb, which part of program (caller, stack or thread) allocated memory ?
In other words, If I have the core file. What kind of information exist in core file that I can use to find out memory allocations ?
Generally speaking, malloc does not save any book-keeping information that would allow you to figure out what parts of your program allocated the memory. Since that information isn't in the live process, it won't be in the core-dump either.
If you want to figure that out, you'll need to use some malloc debug library/program instead. I'd normally recommend Valgrind for this, since it contains an excellent malloc debugger, but Valgrind only works on live processes. There might be some alternative malloc library that you can link against that keeps such information around in such a way that it would also be saved in core-dumps, but if there is, I can't say I know about it.
Smells like some memory leak. Use valgrind on some reproducible run exhibiting the issue (you'll need to start the program again under valgrind). You might not be able to find the issue post-mortem using the core dump alone
BTW, the glib running documentation also suggests calling g_mem_set_vtable (glib_mem_profiler_table) very early at startup (at the beginning of your main)
See also the Boehm conservative garbage collector
At last, it is not important to know which part of the memory exhausted. The available memory is a whole process thing. When running your program of pid 1234, use cat /proc/1234/maps & see proc(5)
Related
I'm currently studying algorithms and advanced data structures: since I'm familiar with C and it does provide a great level of control above implementation and pointer usage I'm using it to test the understanding of the subject so far.
When testing structures that need dinamic things like lists and trees I asked myself: since C doesn't have a garbage collector, if I don't call the free() function in order to deallocate all the variables I dinamically allocate, where does that memory go?
Other related questions incude (sorry for misusing some terms, I don't have much experience in low level abstraction):
Does the compiler use the actual hard drive resources (like a variable is in the x record of my drive) or it "istantiates" a portion of virtual memory to compile and run my programs?
Do I have lots of lists, trees and graphs in my hard drive, all of them involving counts from 0 to 100 or the strings "abcd" and "qwerty"?
Does the OS recognize said data as garbage or I'm stuck with this junk forever until I format the drive?
I'm really curious about it, I never went below the C level of abstraction.
since C doesn't have a garbage collector, if I don't call the free() function in order to deallocate all the variables I dynamically allocate, where does that memory go?
This is not (and cannot really be) defined by the C11 standard (read n1570).
However, let's pretend you run an executable produced by some C compiler on some familiar operating system (like Linux or Windows or MacOSX). Actually you are running some process which has some virtual address space.
The virtual memory and paging subsystem of the operating system kernel would put most useful pages - the resident set size - of that virtual address space in RAM and configure the MMU; read about demand paging & thrashing & page cache & page faults.
When that process terminates (either by nicely exiting or by some abnormal situation, like a segmentation fault) the operating system is releasing every resources used by your process (including the virtual address space of that process).
Read Operating Systems: Three Easy Pieces for much more.
However, if you don't have any operating system, or if your OS or processor don't support virtual memory (think of some Arduino board) things can be widely different. Read about undefined behavior and runtime systems.
On Linux, you can query the address space of a process of pid 1234 by using proc(5). Run in a terminal cat /proc/1234/maps or use pmap(1). From inside the process, read /proc/self/maps as a sequential file. See this.
You could also study the source code of open source standard libraries like GNU libc (above syscalls(2) on Linux) or of musl-libc, or use strace(1) to understand what system calls are done.
C (and other non-garbage-collecting languages) has no concept of garbage at all, and thus no need to collect it somehow - Either you hold a valid pointer to some allocated memory, then it's considered "valuable memory", or you don't, then your program is just wrong - It's as simple as that.
The latter case is something C doesn't even evaluate any further - There's no point in researching what happens in a program "that's wrong" other than fixing it.
Languages like C and C++ use dynamic heap allocation through dedicated functions/operators like malloc and new. This allocates memory on the heap, in RAM. If such a program fails to free the memory once done using it, then the programmer has managed to create a certain kind of bug called memory leak. Meaning that the program now consumes heap memory that cannot be used, since there is nothing in the program pointing at it any longer.
However, all memory allocated by a process is freed by the OS when the process is done executing. If the process failed to clean up its own heap allocations, the OS will do it. It is still good practice to manually clean up the memory though, but for other reasons (exposes latent bugs).
Therefore the only concern with memory leaks is that they cause programs to consume too much RAM while they execute. Once the process is done executing, all memory - including leaked memory - is freed.
There is no relation between the heap and your hard drive, just as there is no relation between the stack and your hard drive. The hard drive is used for storing the executable part of your program, nothing else. The heap, stack and other such memory areas are for storing data when your program is executing. Since they are allocated in RAM, all info in such areas is lost when the program is done executing.
The reason why some languages introduced garbage collection, was to remove the problem with memory leaks. A garbage collector is a background process of sorts, that goes through a program's heap memory and looks for segments of data which no part of the program is pointing at, then free those segments. Since the garbage collector does this, there is no need for free()/ delete.
This comes at the expense of execution speed, since the garbage collector needs to be executed now and then. This is one of many reasons why languages like Java and C# are slower than C and C++ by design. And it is also the reason why C and C++ don't have and never will have a garbage collector, since those languages prioritize execution speed.
If you don't free a resource, it stays allocated. The C compiler knows nothing about hard drives. You can read and write files with C and the appropriate IO libraries. So yes, your hard disk might be littered with stuff from running your software, but the C language or compiler isn't responsible to clean it up. You are. You can clean up your files manually, or code your C programs to clean up after themselves. Get a good book on C.
In languages like C which has no native garbage collection, any instantiated variables are held in volatile memory (RAM not HDD) until such times as either the application releases it or when the application closes. This can cause major issues on machines with limited memory as the memory allocation for the application continues to grow when objects are not 'disposed' throughout its lifecycle until there is no memory left and the application crashes and burns.
In answer to point 2 and 3 (objects on the HDD eg Trees, Graphs), no, they will not be littering your HDD as the objects are only created in memory (RAM) and only live while the application is running, closing the app will release the memory back (mostly) for use by other applications.
See this link for reference to hopefully help understand C Variables a little more.
That memory you are talking about doesn't go anywhere.
It just remains there allocated and unable to be used by any other program until the program that allocated it completes its execution. Then, roughly, the operating system comes and "cleans" all the remains of that application from memory.
It is advised to free the memory yourself since the OS does that way slower than any application would do it (it has to cross-check with every other application running to make sure it doesn't free something it shouldn't be).
Assume I have a C program (running under Linux) which manipulates many data structures, some complex, several of which can grow and shrink but should not in general grow over time. The program is observed to have a gradually increasing RSS over time (more so than can be explained by memory fragmentation). I want to find what is leaking. Running under valgrind is the obvious suggestion here, but valgrind (with --leak-check=full and --show-reachables=yes) shows no leak. I believe this to be because the data structures themselves are correctly being freed on exit, but one of them is growing during the life of the program. For instance, there might be a linked list which is growing linearly over time, with someone forgetting to remove the resource on the list, but the exit cleanup correctly freeing all the items on the list at exit. There is a philosophical question as to whether these are in fact 'leaks' if they are freed, of course (hence the quote marks in the question).
Are there any useful tools to instrument this? What I'd love is the ability to run under valgrind and have it produce a report of current allocations just as it does on exit, but to have this happen on a signal and allow the program to continue. I could then look for what stack trace signatures had growing allocations against them.
I can reliably get a nice large 'core' file from gdb with generate-core-file; is there some way to analyse that off-line, if say I compiled with a handy malloc() debugging library that instrumented malloc()?
I have full access to the source, and can modify it, but I don't really want to instrument every data structure manually, and moreover I'm interested in a general solution to the problem (like valgrind provides) rather than how to address this particular issue.
I've looked for similar questions on here but they appear all to be:
Why does my program leak memory?
How do I detect memory leaks at exit? (no use for me)
How do I detect memory leaks from a core file? (great, but none has a satisfactory answer)
If I was running under Solaris I'm guessing the answer would be 'use this handy dtrace script'.
Valgrind includes a gdbserver. This basically means you can use gdb to connect to it, and e.g. issue a leak dump, or to show all reachable memory while running. Ofcourse, you have to judge whether there is a "memory leak" or not, as valgrind can't know if there's a bug in the application logic that fails to release memory, but still keep references to it.
Run valgrind with the --vgdb=yes flag and then run the commands:
valgrind --vgdb=yes --leak-check=full --show-reachable=yes ./yourprogram
gdb ./yourprogram
(gdb) target remote | vgdb
(gdb) monitor leak_check full reachable any
See the docs for more info, here and here
You can also do this programatically in your program
#include <valgrind/memcheck.h>
and at an appropriate place in the code do:
VALGRIND_DO_LEAK_CHECK;
(iirc that'll show reachable memory too, as long as valgrind is run with --show-reachable=yes
There's the Valgrind Massif tool which shows general memory usage of your application, not just for leaked memory. It breaks down malloc()s and free()s by calling functions and their backtraces, so you can see which functions keep allocating memory without releasing it. This can be an excellent tool for finding leaks of the type you mentioned.
Unfortunately the tooling around Massif is a bit weird... The ms_print tool provided with Valgrind is only useful for the most basic tasks; for real work you probably want something that displays a graph. There are several tools for this strewn around the net - see eg. Valgrind Massif tool output graphical interface? .
I've written a debugger using ptrace(2) that is mainly for auditing system calls and redirecting standard IO of a child process. I would also like to detect memory leaks using this debugger.
I thought that it might be as easy as counting references to the system call brk(2), but it isn't. Unfortunately (or fortunately), Linux seems to call brk(2) at the end of the program regardless of whether or not the memory was properly freed.
I've seen this in a program that calls malloc(3) and free(3) and a program that just calls malloc(3) - they both have equal counts of brk(2) calls by the time the program has called exit_group(2), which is happens on return (perhaps I could be interpreting those results incorrectly?).
Or, perhaps exit_group(2) isn't equivalent to 'return' from main, and I should be setting a different break point for auditing the call count of brk(2).
I found a similar question here, but I still haven't found an answer.
I understand that Valgrind is a perfect tool for this, but it would cause considerable overhead.
Does anyone have helpful information on detecting memory leaks with ptrace(2)? Is possible with ptrace(2)? Is there a more practical way? Is there an API for memory debugging child processes?
Edit:
If there's other functions involved with allocate memory, I would count those too. On the page for malloc, it says that mmap(2) is also used in memory allocation. So, I would be counting that too.
Use gdb's heap extension. It will do what you want. IF you want to use it programatically, just pipe the results to your application to do post processing:
https://fedorahosted.org/gdb-heap/
I am porting a game built in c to use opengl for porting reasons. Everything was going fine until, for some reasons, the malloc functions of the game stopped working.
I has been searching for an answer to this. The only thing I found about it is that malloc is returning NULL. A very simple malloc that creates a simple structure of a few bytes.
I made a some tries and I wrote the command inside a loop. And my surprise was that it failed the first 10 times, but after that the command worked and the game started. The structure has been created several times after that with no problem.
I would say to leave it as it is, but I am sure there is something wrong behind and in other systems may not work correctly. That's why I want to ask what kind of problem I am having, why and how to avoid it. The environment is not very friendly and I lack of debugging tools, so I would appreciate as many details as possible.
thank you.
EDIT:
The code is simple.
ObjectBase* newcoin;
newcoin= (ObjectBase*)calloc(1,sizeof(ObjectBase));
while the ObjectBase structure is very small. No more than 200 bytes.
The hardware is a windows 7 based computer with 4 GB or memory. Even with this, the error is:
Visual C++ CRT: Not enough memory to complete call to strerror
It worked fine before.
More problems. I am having the same problem when loading files from disk. It happens about 10 to 15 times and then works correctly.
The problem happens always. Each time I restart the application, it crashes.
Use valgrind to debug possible memory leaks in your program.
If you checked that your program is not leaking or misbehaving w.r.t. malloc, it may happen that malloc returns NULL because no memory is available.
It could even happen that malloc returns NULL, then some third-party library releases some memory with free, then malloc could give you again some fresh memory.
You might also consider using Boehm's conservative garbage collector that is use GC_malloc instead of malloc and not bother much about free-ing memory.
If on Linux, use the /proc pseudo-file system to learn about your process (e.g. /proc/1234/maps for process of pid 1234, also /proc/self/maps from inside the process, and /proc/self/statm etc). See also the pmap command.
I have a Linux app (written in C) that allocates large amount of memory (~60M) in small chunks through malloc() and then frees it (the app continues to run then). This memory is not returned to the OS but stays allocated to the process.
Now, the interesting thing here is that this behavior happens only on RedHat Linux and clones (Fedora, Centos, etc.) while on Debian systems the memory is returned back to the OS after all freeing is done.
Any ideas why there could be the difference between the two or which setting may control it, etc.?
I'm not certain why the two systems would behave differently (probably different implementations of malloc from different glibc's). However, you should be able to exert some control over the global policy for your process with a call like:
mallopt(M_TRIM_THRESHOLD, bytes)
(See this linuxjournal article for details).
You may also be able to request an immediate release with a call like
malloc_trim(bytes)
(See malloc.h). I believe that both of these calls can fail, so I don't think you can rely on them working 100% of the time. But my guess is that if you try them out you will find that they make a difference.
Some mem handler dont present the memory as free before it is needed. It instead leaves the CPU to do other things then finalize the cleanup. If you wish to confirm that this is true, then just do a simple test and allocate and free more memory in a loop more times than you have memeory available.