Does my program need to be able to handle SIGINT? - c

Should I worry about handling the event that user passes SIGINT in the middle of using my program?
The program in question deals with heap allocations and frees, so I am worried that such a situation would cause a memory leak. When I pass SIGINT in the middle of using the program, Valgrind states:
==30173== Process terminating with default action of signal 2 (SIGINT)
==30173== at 0x4ACC142: read (read.c:26)
==30173== by 0x4A4ED1E: _IO_file_underflow##GLIBC_2.2.5 (fileops.c:517)
==30173== by 0x4A41897: getdelim (iogetdelim.c:73)
==30173== by 0x109566: main (main.c:55)
==30173==
==30173== HEAP SUMMARY:
==30173== in use at exit: 1,000 bytes in 1 blocks
==30173== total heap usage: 3 allocs, 2 frees, 3,048 bytes allocated
==30173==
==30173== LEAK SUMMARY:
==30173== definitely lost: 0 bytes in 0 blocks
==30173== indirectly lost: 0 bytes in 0 blocks
==30173== possibly lost: 0 bytes in 0 blocks
==30173== still reachable: 1,000 bytes in 1 blocks
==30173== suppressed: 0 bytes in 0 blocks
==30173== Rerun with --leak-check=full to see details of leaked memory
==30173==
==30173== For lists of detected and suppressed errors, rerun with: -s
==30173== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

The answer is OS-dependent. Most modern operating systems will clean up memory allocated by your process once it is killed (Windows, Linux, *nix in general, and more). This is usually just part of the OS memory isolation and protection system, where each process gets its own virtual memory mapping and the physical pages corresponding to that mapping are allocated / freed by way of reference counting (a killed / exited process will decrement the reference counts to its mapped physical pages and free them if they reach zero).
If you plan on running your process on obscure embedded systems with no such guarantees with respect to memory management, then perhaps you might need to worry about such a thing. Otherwise, if memory management is your only concern, then it's a non-issue.
If you want to account for other things which should happen on exit (e.g. saving state), then you will certainly need to trap SIGINT, likely along with other signals as well.

Related

valgrind not able find memory leak

I have encountered a weird issue. A process(written in c) is leaking memory but I am not able to locate why it is happening. Memory usage is increasing continuously when process handles traffic and at some point OS(linux) is killing it with error 'out of memory'.
I tried to debug this using valgrind with the following flags:
--show-reachable=yes --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose --track-fds=yes --num-callers=20 --log-file=/tmp/valgrind-out.txt
Output file is as follows:
==5564== LEAK SUMMARY:
==5564== definitely lost: 0 bytes in 0 blocks
==5564== indirectly lost: 0 bytes in 0 blocks
==5564== possibly lost: 646,916 bytes in 1,156 blocks
==5564== still reachable: 4,742,112 bytes in 2,191 blocks
==5564== suppressed: 0 bytes in 0 blocks
Definitely lost is shown as 0 and there is no indication on where it is leaking. I have gone through still reachable segment, they all seem fine.
I wont be able to post code as it is a huge code with 100k+ lines. Basically what it does it sends some packets over tcp socket as a client. Sever is a simple python script which replies with response. My codes works as expected. This leak is the only trouble.
Any suggestion on debugging this issue?

c programming - difference between compiling in Ubuntu and compiling in Alpine - gcc - valgrind

I'm trying to understand some differences I've noticed when compiling a simple C program with gcc on Ubuntu (canonical ubuntu) and on Alpine (a docker container).
The program is the following:
int main(void)
{
printf("test\n");
return 0;
}
The command used to compile is the same for each terminal (Ubuntu and Alpine).
Valgrind detects no error on Ubuntu and 1 error on Alpine:
==311== Invalid free() / delete / delete[] / realloc()
==311== at 0x4C939EA: free (vg_replace_malloc.c:530)
==311== by 0x4057B69: ??? (in /lib/ld-musl-x86_64.so.1)
==311== Address 0x4e9b180 is in a rw- mapped file
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so segment
==311==
test
==311==
==311== HEAP SUMMARY:
==311== in use at exit: 404 bytes in 1 blocks
==311== total heap usage: 1 allocs, 1 frees, 404 bytes allocated
==311==
==311== LEAK SUMMARY:
==311== definitely lost: 0 bytes in 0 blocks
==311== indirectly lost: 0 bytes in 0 blocks
==311== possibly lost: 0 bytes in 0 blocks
==311== still reachable: 404 bytes in 1 blocks
==311== suppressed: 0 bytes in 0 blocks
==311== Rerun with --leak-check=full to see details of leaked memory
==311==
==311== For counts of detected and suppressed errors, rerun with: -v
==311== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
What is the explanation for that?
Valgrind calls special glibc functions to deallocate memory on process exit (while normally, glibc just lets the kernel do that). Musl likely doesn't have that because it is poor bloat.
Valgrind also has suppression files to deal with false positives or useless reports from system libraries. Some porting work is required to create them, and it looks like Alpine hasn't done that yet, or the files have become obsolete due to further musl development.
Sometimes, suppression files require debuginfo symbols, and valgrind couldn't find them in the run you quoted, so this is another thing to try.

Valgrind showing over 200 allocs for a hello world program on OS X?

I wrote a linked list in C today at work on a Linux machine and everything checked out in Valgrind. Then I ran the same test (a handful of pushes and then deleting the list) at home on OS X and got a crazy amount of allocs.
==4344== HEAP SUMMARY:
==4344== in use at exit: 26,262 bytes in 187 blocks
==4344== total heap usage: 267 allocs, 80 frees, 32,374 bytes allocated
==4344==
==4344== LEAK SUMMARY:
==4344== definitely lost: 0 bytes in 0 blocks
==4344== indirectly lost: 0 bytes in 0 blocks
==4344== possibly lost: 0 bytes in 0 blocks
==4344== still reachable: 0 bytes in 0 blocks
==4344== suppressed: 26,262 bytes in 187 blocks
==4344==
==4344== For counts of detected and suppressed errors, rerun with: -v
==4344== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I know the code is fine and doesn't have any leaks. So I just commented out the list test and compiled with only printf("test\n"); in the main, and it showed 263 allocs with 76 frees (I had 4 intentional allocs in the list test). Why am I getting so many allocs on OS X? Is this just something the OS did? I don't understand why I'd have 263 allocs when I just did a printf...
OS X has a very bad architecture. Because libdl, libdyld, libm, libc and some other libraries are "packed" into libSystem, all of them are initialized when the library is loaded. Most of them come from dyld. Dyld is written in C and C++, that's why C++ part may push up number of allocs.
This is only Apple thing, not OS X thing. I have written an alternate C library. It does not have many "not-needed allocs".
Also, allocs are caused by opening FILE *s. Note that 3 streams (stdin, stdout and stderr) are initialized on run.
Valgrind support on OS X is currently being actively worked on. Your best approach is to ensure you are using a SVN trunk build, and update frequently.
The errors Valgrind is reporting to you are present within the OS X system libraries. These are not the fault of your program, but because even simple programs including these system libraries Valgrind continues to pick them up. Suppressions within Valgrind trunk are continually being updated to catch these issues, allowing you to focus on the real problems that may be present within your code.
The following commands will allow you to use Valgrind trunk, if you're not already:
svn co svn://svn.valgrind.org/valgrind/trunk valgrind
cd valgrind
./autogen.sh
./configure
make -j4
sudo make install
Full disclosure: I'm one of the Valgrind developers who contributed patches to support OS X 10.11

C - memory leak in case of big input [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
For an assignment, I have to order a list of students. Each one is represented by a number (string of size 15), his father's lastname (string 20), his mother's lastname (string 20) and his firstname (string 20 also).
I did a program that build from a file the list of students and order it (I use a merge sort to do so).
When I run the program on small number of students (<10 000) everything is fine (no memory leak or anything according to valgrind).
However, as soon as I try to use it on bigger ones (more than 100 000), I get a segmentation fault 11. I investigated with Valgrind and it says the error comes from the strcy or strcasecmp functions, and renders :
==2433== Invalid write of size 8
==2433== at 0x4019BD: merge (sort.c:59)
==2433== by 0x40173B: sortBeginEnd (sort.c:38)
==2433== by 0x4014B0: sortWithoutInterval (sort.c:9)
==2433== by 0x401EE0: firstSort (sort.c:166)
==2433== by 0x4009EB: main (main.c:44)
==2433== Address 0xffe79ac88 is on thread 1's stack
==2433==
==2433==
==2433== Process terminating with default action of signal 11 (SIGSEGV)
==2433== Access not within mapped region at address 0xFFE79AC88
==2433== at 0x4019BD: merge (sort.c:59)
==2433== If you believe this happened as a result of a stack
==2433== overflow in your program's main thread (unlikely but
==2433== possible), you can try to increase the size of the
==2433== main thread stack using the --main-stacksize= flag.
==2433== The main thread stack size used in this run was 8388608.
==2433==
==2433== Process terminating with default action of signal 11 (SIGSEGV)
==2433== Access not within mapped region at address 0xFFE79AC81
==2433== at 0x4A256B0: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so)
==2433== If you believe this happened as a result of a stack
==2433== overflow in your program's main thread (unlikely but
==2433== possible), you can try to increase the size of the
==2433== main thread stack using the --main-stacksize= flag.
==2433== The main thread stack size used in this run was 8388608.
==2433==
==2433== HEAP SUMMARY:
==2433== in use at exit: 12,800,101 bytes in 500,007 blocks
==2433== total heap usage: 500,008 allocs, 1 frees, 12,800,669 bytes allocated
==2433==
==2433== LEAK SUMMARY:
==2433== definitely lost: 0 bytes in 0 blocks
==2433== indirectly lost: 0 bytes in 0 blocks
==2433== possibly lost: 0 bytes in 0 blocks
==2433== still reachable: 12,800,101 bytes in 500,007 blocks
==2433== suppressed: 0 bytes in 0 blocks
==2433== Rerun with --leak-check=full to see details of leaked memory
==2433==
==2433== For counts of detected and suppressed errors, rerun with: -v
==2433== ERROR SUMMARY: 7452721 errors from 31 contexts (suppressed: 0 from 0)
Could the error be that I use too much memory (each student represents 79 characters = 316 bytes and I have 100 000 of them so it is 31 600 000 bytes if I am right) ?
PS : i am not really familiar with the concept of stack and heap
EDIT :
"Everything is fine" valgrind report :
==2454==
==2454== HEAP SUMMARY:
==2454== in use at exit: 0 bytes in 0 blocks
==2454== total heap usage: 50,008 allocs, 50,008 frees, 1,280,669 bytes allocated
==2454==
==2454== All heap blocks were freed -- no leaks are possible
==2454==
==2454== For counts of detected and suppressed errors, rerun with: -v
==2454== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
EDIT2 :
The code is available here if you want to check it.
EDIT LAST :
I finally found the solution thanks to #Lundin's answer. The problem was that i was not using a malloc to allocate the temporary arrays for the merge part of the mergeSort.
I will investigate a bit more the question of heap/stack to fully understand the problem.
You aren't even mentioning which system this is for. Because of Valgrind I assume Linux. You don't mention where you allocate the variables. Apparently not on the heap since Valgrid only reports 12.8kb there.
If I remember correctly (and I know very little of Linux) processes have a stack size of roughly 8Mb.
316 * 10000 = 3.16 Mb.
316 * 100000 = 31.60 Mb.
Qualified guess: if you are allocating your variables in any other way than with malloc, then stack overflow is the source of the described problems.
Whenever using large amounts of memory in your program, you must allocate them dynamically on the heap.
the stack is the place, where your function holds its local/temporary data (parameters and local variables). it is organized as stack of papers, so when you call a function, the parameters are put onto the stack, and when the function finishes, everything except the result is discarded from the stack. normally the stack has a limited size.
the heap is the memory, where your allocated data is kept (f.e. malloc()). you can have different heaps (for your application, for each process and system wide)

Valrind reports "still reachable" in empyt function

I'm using valgrind to check about the memory usage of my C application. After the first tests valgrind reports:
"still reachable: 2,248 bytes in 1 blocks".
I checked the code but I was not able to find the problem at mere sight. So I started to comment sections of the code to try to find the problem.
I was shocked when in my code I only have left
int main(void)
{
};
and STILL get the message, with the only difference in the amount of bytes.
I'm really puzzled with this...
Here is the complete messagge:
Running with options : valgrind --leak-check=full --show-reachable=yes
==2557== HEAP SUMMARY:
==2557== in use at exit: 2,248 bytes in 1 blocks
==2557== total heap usage: 362 allocs, 361 frees, 14,579 bytes allocated
==2557==
==2557== 2,248 bytes in 1 blocks are still reachable in loss record 1 of 1
==2557== at 0x4006171: calloc (vg_replace_malloc.c:593)
==2557== by 0x4D72250B: monstartup (in /usr/lib/libc-2.15.so)
==2557== by 0x8048650: __gmon_start__ (in /home/elias/Documents/SL_HTTP/Endosos/bin/Debug/Endosos)
==2557== by 0x4005421: ??? (in /usr/local/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==2557==
==2557== LEAK SUMMARY:
==2557== definitely lost: 0 bytes in 0 blocks
==2557== indirectly lost: 0 bytes in 0 blocks
==2557== possibly lost: 0 bytes in 0 blocks
==2557== still reachable: 2,248 bytes in 1 blocks
==2557== suppressed: 0 bytes in 0 blocks
==2557==
==2557== For counts of detected and suppressed errors, rerun with: -v
==2557== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Profiling timer expired
I'm compiling with gcc 4.7.2 in Fedrora 17
Any advice will be appreciated. Thanks.
This is perfectly fine and safe to ignore. In this case this is memory that seems to have been allocated by profiling (you're probably compiling code with profiling enabled or linking to some library that does).
Your environment will do a bunch of things to set up before calling main and those things can allocate memory. Since they know that this memory will be used until the program exits they don't bother to free it on exit because that just takes time for no benefit. Most of that memory will be reported as "still reachable" by valgrind and can be safely ignored.
Thanks to all.
You were right.
I'm using Code:Blocks 12.11 and by default it had enable -pg in the compiler settings.

Resources