Linux - GeneralThis Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Here is a test code for memory alloc and free. It is to detect whether the allocs and frees match. From the result, after backtrace call, there is some memory alloc, but it does not free these memories after calling or the process exit. Why? Nomorlly, the memory alloced need to be freed after use, or the memory will leak.
But I run this program for about some times, and find that though the system memory does not real leak,the free memory decreases, and the cache increases(Use free command).
/* Obtain a backtrace and print it to stdout. */
void print_trace (void)
{
void *array[10];
size_t size;
char **strings;
size_t i;
size = backtrace (array, 10);
}
/* A dummy function to make the backtrace more interesting. */
void dummy_function (void)
{
print_trace ();
}
int main (void)
{
my_init_hook();
dummy_function ();
return 0;
}
Valgrind results:
[root@localhost memory]# valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./test2
==4018== Memcheck, a memory error detector.
==4018== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==4018== Using LibVEX rev 1658, a library for dynamic binary translation.
==4018== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==4018== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==4018== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==4018== For more details, rerun with: -v
==4018==
==4018==
==4018== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==4018== malloc/free: in use at exit: 904 bytes in 5 blocks.
==4018== malloc/free: 5 allocs, 0 frees, 904 bytes allocated.
==4018== For counts of detected errors, rerun with: -v
==4018== searching for pointers to 5 not-freed blocks.
==4018== checked 52,300 bytes.
==4018==
==4018== 19 bytes in 1 blocks are still reachable in loss record 1 of 5
==4018== at 0x40053C0: malloc (vg_replace_malloc.c:149)
==4018== by 0x4F389724: _dl_new_object (in /lib/ld-2.5.so)
==4018== by 0x4F385020: _dl_map_object_from_fd (in /lib/ld-2.5.so)
==4018== by 0x4F387333: _dl_map_object (in /lib/ld-2.5.so)
==4018== by 0x4F3905B8: dl_open_worker (in /lib/ld-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F3900D1: _dl_open (in /lib/ld-2.5.so)
==4018== by 0x4F4A34A1: do_dlopen (in /lib/libc-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F4A3654: __libc_dlopen_mode (in /lib/libc-2.5.so)
==4018== by 0x4F480FD8: init (in /lib/libc-2.5.so)
==4018== by 0x4F481172: backtrace (in /lib/libc-2.5.so)
==4018==
==4018==
==4018== 19 bytes in 1 blocks are still reachable in loss record 2 of 5
==4018== at 0x40053C0: malloc (vg_replace_malloc.c:149)
==4018== by 0x4F387883: _dl_map_object (in /lib/ld-2.5.so)
==4018== by 0x4F3905B8: dl_open_worker (in /lib/ld-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F3900D1: _dl_open (in /lib/ld-2.5.so)
==4018== by 0x4F4A34A1: do_dlopen (in /lib/libc-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F4A3654: __libc_dlopen_mode (in /lib/libc-2.5.so)
==4018== by 0x4F480FD8: init (in /lib/libc-2.5.so)
==4018== by 0x4F481172: backtrace (in /lib/libc-2.5.so)
==4018== by 0x8048596: print_trace (in /root/memory/test2)
==4018== by 0x80485A6: dummy_function (in /root/memory/test2)
==4018==
==4018==
==4018== 28 bytes in 1 blocks are still reachable in loss record 3 of 5
==4018== at 0x40053C0: malloc (vg_replace_malloc.c:149)
==4018== by 0x4F38B978: _dl_map_object_deps (in /lib/ld-2.5.so)
==4018== by 0x4F390614: dl_open_worker (in /lib/ld-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F3900D1: _dl_open (in /lib/ld-2.5.so)
==4018== by 0x4F4A34A1: do_dlopen (in /lib/libc-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F4A3654: __libc_dlopen_mode (in /lib/libc-2.5.so)
==4018== by 0x4F480FD8: init (in /lib/libc-2.5.so)
==4018== by 0x4F481172: backtrace (in /lib/libc-2.5.so)
==4018== by 0x8048596: print_trace (in /root/memory/test2)
==4018== by 0x80485A6: dummy_function (in /root/memory/test2)
==4018==
==4018==
==4018== 224 bytes in 1 blocks are still reachable in loss record 4 of 5
==4018== at 0x40046FF: calloc (vg_replace_malloc.c:279)
==4018== by 0x4F38E293: _dl_check_map_versions (in /lib/ld-2.5.so)
==4018== by 0x4F3908D0: dl_open_worker (in /lib/ld-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F3900D1: _dl_open (in /lib/ld-2.5.so)
==4018== by 0x4F4A34A1: do_dlopen (in /lib/libc-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F4A3654: __libc_dlopen_mode (in /lib/libc-2.5.so)
==4018== by 0x4F480FD8: init (in /lib/libc-2.5.so)
==4018== by 0x4F481172: backtrace (in /lib/libc-2.5.so)
==4018== by 0x8048596: print_trace (in /root/memory/test2)
==4018== by 0x80485A6: dummy_function (in /root/memory/test2)
==4018==
==4018==
==4018== 614 bytes in 1 blocks are still reachable in loss record 5 of 5
==4018== at 0x40046FF: calloc (vg_replace_malloc.c:279)
==4018== by 0x4F3894BA: _dl_new_object (in /lib/ld-2.5.so)
==4018== by 0x4F385020: _dl_map_object_from_fd (in /lib/ld-2.5.so)
==4018== by 0x4F387333: _dl_map_object (in /lib/ld-2.5.so)
==4018== by 0x4F3905B8: dl_open_worker (in /lib/ld-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F3900D1: _dl_open (in /lib/ld-2.5.so)
==4018== by 0x4F4A34A1: do_dlopen (in /lib/libc-2.5.so)
==4018== by 0x4F38CB45: _dl_catch_error (in /lib/ld-2.5.so)
==4018== by 0x4F4A3654: __libc_dlopen_mode (in /lib/libc-2.5.so)
==4018== by 0x4F480FD8: init (in /lib/libc-2.5.so)
==4018== by 0x4F481172: backtrace (in /lib/libc-2.5.so)
==4018==
==4018== LEAK SUMMARY:
==4018== definitely lost: 0 bytes in 0 blocks.
==4018== possibly lost: 0 bytes in 0 blocks.
==4018== still reachable: 904 bytes in 5 blocks.
==4018== suppressed: 0 bytes in 0 blocks.
Can somebody explain this? Whether the backtrace call really memory leak?
> Here is a test code for memory alloc and free. It is to detect whether the allocs and frees match. From the result, after backtrace call, there is some memory alloc, but it does not free these memories after calling or the process exit. Why? Nomorlly, the memory alloced need to be freed after use, or the memory will leak.
This statement is only true within a single process. In that context one needs to free the memory so that it can be reused. However, all this activity is unseen by the kernel; when the process terminates, the kernel recovers it all.
You have not leaked memory so long as the cache + used + free remains constant. A leak would show as a decrease in the amount of memory that the kernel controls.
It's not unusual for these numbers to jitter a great deal -- the memory management inside the kernel is constantly reoptimizing.
I did more tests, all the memory alloced will be returned to OS after the process exit without "free" operations.
But I am still confused why these memories the backtrace alloced are not returned to OS after backtrace is called? Is this a memory leak for the process during its running status?
Quote:
Originally Posted by 4dummies
> Here is a test code for memory alloc and free. It is to detect whether the allocs and frees match. From the result, after backtrace call, there is some memory alloc, but it does not free these memories after calling or the process exit. Why? Nomorlly, the memory alloced need to be freed after use, or the memory will leak.
This statement is only true within a single process. In that context one needs to free the memory so that it can be reused. However, all this activity is unseen by the kernel; when the process terminates, the kernel recovers it all.
You have not leaked memory so long as the cache + used + free remains constant. A leak would show as a decrease in the amount of memory that the kernel controls.
It's not unusual for these numbers to jitter a great deal -- the memory management inside the kernel is constantly reoptimizing.
1. Every time run this test program, it will alloc memories for 5 times, like this:
@@@ 0xb7869c6f + 0x804b008 0x13
@@@ 0xb786f0bb + 0x804b020 0x272
@@@ 0xb786f345 + 0x804b298 0x13
@@@ 0xb7871ca7 + 0x804b2b0 0x1c
@@@ 0xb7874dee + 0x804b2d0 0xe0
2. If the backtrace is called more than 2 times, it will not alloc memory after 1st call.
3. Tracing in the backtrace, find that the memories are alloced by init() function in it. Following is the details with gcc-2.9:
[I]((gdb) n
3546 return (*hook)(bytes, RETURN_ADDRESS (0));
(gdb) n
@@@ 0xb7fe4c6f + 0x804b008 0x13
3576 }
(gdb) bt
#0 *__GI___libc_malloc (bytes=19) at malloc.c:3576
#1 0xb7fe4c6f in local_strdup (s=0xb7e3e52f "/lib/libgcc_s.so.1")
at dl-load.c:170
#2 0xb7fe7b0c in _dl_map_object (loader=0xb7fff668,
name=0xb7f790f9 "libgcc_s.so.1", preloaded=0, type=2, trace_mode=0,
mode=-1879048191, nsid=0) at dl-load.c:2150
#3 0xb7ff25e7 in dl_open_worker (a=0xbffff330) at dl-open.c:293
#4 0xb7fee356 in _dl_catch_error (objname=0xbffff358, errstring=0xbffff354,
mallocedp=0xbffff35f, operate=0xb7ff24a0 <dl_open_worker>, args=0xbffff330)
at dl-error.c:178
#5 0xb7ff1fee in _dl_open (file=0xb7f790f9 "libgcc_s.so.1", mode=-2147483647,
caller_dlopen=0x0, nsid=-2, argc=1, argv=0xbffff614, env=0xbffff61c)
at dl-open.c:596
#6 0xb7f5bfe2 in do_dlopen (ptr=0xbffff4b0) at dl-libc.c:86
#7 0xb7fee356 in _dl_catch_error (objname=0xbffff48c, errstring=0xbffff488,
mallocedp=0xbffff493, operate=0xb7f5bf80 <do_dlopen>, args=0xbffff4b0)
at dl-error.c:178
#8 0xb7f5c0e1 in dlerror_run (operate=<value optimized out>,
args=<value optimized out>) at dl-libc.c:47
#9 0xb7f5c206 in *__GI___libc_dlopen_mode (name=0x0, mode=-2147483647)
at dl-libc.c:160
#10 0xb7f379f8 in init () at ../sysdeps/i386/backtrace.c:44
#11 0xb7f37b8d in *__GI___backtrace (array=0xbffff524, size=10)
---Type <return> to continue, or q <return> to quit---
at ../sysdeps/i386/backtrace.c:121
#12 0x0804861d in print_trace () at test.c:50
#13 0x0804862d in dummy_function () at test.c:57
#14 0x0804864a in main () at test.c:63
(gdb)
(gdb) n
2242 return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode,
(gdb) n
@@@ 0xb7fea0bb + 0x804b020 0x272
@@@ 0xb7fea345 + 0x804b298 0x13
2244 }
(gdb) bt
#0 _dl_map_object (loader=0x0, name=0xb7f790f9 "libgcc_s.so.1", preloaded=0,
type=2, trace_mode=0, mode=-1879048191, nsid=0) at dl-load.c:2244
#1 0xb7ff25e7 in dl_open_worker (a=0xbffff330) at dl-open.c:293
#2 0xb7fee356 in _dl_catch_error (objname=0xbffff358, errstring=0xbffff354,
mallocedp=0xbffff35f, operate=0xb7ff24a0 <dl_open_worker>, args=0xbffff330)
at dl-error.c:178
#3 0xb7ff1fee in _dl_open (file=0xb7f790f9 "libgcc_s.so.1", mode=-2147483647,
caller_dlopen=0x0, nsid=-2, argc=1, argv=0xbffff614, env=0xbffff61c)
at dl-open.c:596
#4 0xb7f5bfe2 in do_dlopen (ptr=0xbffff4b0) at dl-libc.c:86
#5 0xb7fee356 in _dl_catch_error (objname=0xbffff48c, errstring=0xbffff488,
mallocedp=0xbffff493, operate=0xb7f5bf80 <do_dlopen>, args=0xbffff4b0)
at dl-error.c:178
#6 0xb7f5c0e1 in dlerror_run (operate=<value optimized out>,
args=<value optimized out>) at dl-libc.c:47
#7 0xb7f5c206 in *__GI___libc_dlopen_mode (name=0xb7fd04a4 "a",
mode=-2147483647) at dl-libc.c:160
#8 0xb7f379f8 in init () at ../sysdeps/i386/backtrace.c:44
#9 0xb7f37b8d in *__GI___backtrace (array=0xbffff524, size=10)
at ../sysdeps/i386/backtrace.c:121
#10 0x0804861d in print_trace () at test.c:50
#11 0x0804862d in dummy_function () at test.c:57
#12 0x0804864a in main () at test.c:63
(gdb)
##############################################################
330 _dl_map_object_deps (new, NULL, 0, 0,
(gdb) n
@@@ 0xb7fecca7 + 0x804b2b0 0x1c
334 for (i = 0; i < new->l_searchlist.r_nlist; ++i)
(gdb) bt
#0 dl_open_worker (a=0xbffff330) at dl-open.c:334
#1 0xb7fee356 in _dl_catch_error (objname=0xbffff358, errstring=0xbffff354,
mallocedp=0xbffff35f, operate=0xb7ff24a0 <dl_open_worker>, args=0xbffff330)
at dl-error.c:178
#2 0xb7ff1fee in _dl_open (file=0xb7f790f9 "libgcc_s.so.1", mode=-2147483647,
caller_dlopen=0x0, nsid=-2, argc=1, argv=0xbffff614, env=0xbffff61c)
at dl-open.c:596
#3 0xb7f5bfe2 in do_dlopen (ptr=0xbffff4b0) at dl-libc.c:86
#4 0xb7fee356 in _dl_catch_error (objname=0xbffff48c, errstring=0xbffff488,
mallocedp=0xbffff493, operate=0xb7f5bf80 <do_dlopen>, args=0xbffff4b0)
at dl-error.c:178
#5 0xb7f5c0e1 in dlerror_run (operate=<value optimized out>,
args=<value optimized out>) at dl-libc.c:47
#6 0xb7f5c206 in *__GI___libc_dlopen_mode (name=0x0, mode=-2147483647)
at dl-libc.c:160
#7 0xb7f379f8 in init () at ../sysdeps/i386/backtrace.c:44
#8 0xb7f37b8d in *__GI___backtrace (array=0xbffff524, size=10)
at ../sysdeps/i386/backtrace.c:121
#9 0x0804861d in print_trace () at test.c:50
#10 0x0804862d in dummy_function () at test.c:57
#11 0x0804864a in main () at test.c:63
(gdb)
##############################################################
(gdb) n
336 (void) _dl_check_map_versions (new->l_searchlist.r_list->l_real,
(gdb) n
@@@ 0xb7fefdee + 0x804b2d0 0xe0
334 for (i = 0; i < new->l_searchlist.r_nlist; ++i)
(gdb) bt
#0 dl_open_worker (a=0xbffff330) at dl-open.c:334
#1 0xb7fee356 in _dl_catch_error (objname=0xbffff358, errstring=0xbffff354,
mallocedp=0xbffff35f, operate=0xb7ff24a0 <dl_open_worker>, args=0xbffff330)
at dl-error.c:178
#2 0xb7ff1fee in _dl_open (file=0xb7f790f9 "libgcc_s.so.1", mode=-2147483647,
caller_dlopen=0x0, nsid=-2, argc=1, argv=0xbffff614, env=0xbffff61c)
at dl-open.c:596
#3 0xb7f5bfe2 in do_dlopen (ptr=0xbffff4b0) at dl-libc.c:86
#4 0xb7fee356 in _dl_catch_error (objname=0xbffff48c, errstring=0xbffff488,
mallocedp=0xbffff493, operate=0xb7f5bf80 <do_dlopen>, args=0xbffff4b0)
at dl-error.c:178
#5 0xb7f5c0e1 in dlerror_run (operate=<value optimized out>,
args=<value optimized out>) at dl-libc.c:47
#6 0xb7f5c206 in *__GI___libc_dlopen_mode (name=0x804b020 "",
mode=-2147483647) at dl-libc.c:160
#7 0xb7f379f8 in init () at ../sysdeps/i386/backtrace.c:44
#8 0xb7f37b8d in *__GI___backtrace (array=0xbffff524, size=10)
at ../sysdeps/i386/backtrace.c:121
#9 0x0804861d in print_trace () at test.c:50
#10 0x0804862d in dummy_function () at test.c:57
#11 0x0804864a in main () at test.c:63
(gdb)
Last edited by lagignition; 10-20-2010 at 03:13 AM.
Reason: More correct debug information
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.