j256 / dmalloc Goto Github PK
View Code? Open in Web Editor NEWDebug Malloc memory allocation debugging C library
Home Page: http://dmalloc.com/
License: ISC License
Debug Malloc memory allocation debugging C library
Home Page: http://dmalloc.com/
License: ISC License
Hi,
We have been using dmalloc
as part of our tools set to verify that our core libraries are free of memory leaks. However, recently we have discovered that using printf
or fgetc
would cause dmalloc to throw the following warnings in dmalloc.log.
not freed: '0x7f2e20d36808|s1' (1182 bytes) from 'unknown'
To demonstrate the issue, below is a very simple program that we have used to reproduce the errors:
#include <stdio.h>
#include <stdlib.h>
#include "dmalloc.h"
void main() {
dmalloc_debug_setup("log-stats,log-non-free,check-fence,log=dmalloc.log");
printf("Hello World\n");
fgetc(stdin);
}
Compile the program with:
gcc test.c -ldmalloc -g -o test
Run and I get the following results:
1630587465: 2: Dmalloc version '5.5.2' from 'http://dmalloc.com/'
1630587465: 2: flags = 0x403, logfile 'dmalloc.log'
1630587465: 2: interval = 0, addr = 0, seen # = 0, limit = 0
1630587465: 2: threads enabled, lock-on = 0, lock-init = 2
1630587465: 2: starting time = 1630587464
1630587465: 2: process pid = 2079
1630587465: 2: Dumping Chunk Statistics:
1630587465: 2: basic-block 4096 bytes, alignment 8 bytes
1630587465: 2: heap address range: 0x7f343a6e0000 to 0x7f343a712000, 204800 bytes
1630587465: 2: user blocks: 4 blocks, 8192 bytes (33%)
1630587465: 2: admin blocks: 2 blocks, 8192 bytes (33%)
1630587465: 2: total blocks: 6 blocks, 24576 bytes
1630587465: 2: heap checked 0
1630587465: 2: alloc calls: malloc 2, calloc 0, realloc 0, free 0
1630587465: 2: alloc calls: recalloc 0, memalign 0, posix_memalign 0, valloc 0
1630587465: 2: alloc calls: new 0, delete 0
1630587465: 2: current memory in use: 8192 bytes (2 pnts)
1630587465: 2: total memory allocated: 8192 bytes (2 pnts)
1630587465: 2: max in use at one time: 8192 bytes (2 pnts)
1630587465: 2: max alloced with 1 call: 4096 bytes
1630587465: 2: max unused memory space: 8192 bytes (50%)
1630587465: 2: top 10 allocations:
1630587465: 2: total-size count in-use-size count source
1630587465: 2: 0 0 0 0 Total of 0
1630587465: 2: Dumping Not-Freed Pointers Changed Since Start:
1630587465: 2: not freed: '0x7f343a6f0008|s1' (4096 bytes) from 'unknown'
1630587465: 2: not freed: '0x7f343a710008|s1' (4096 bytes) from 'unknown'
1630587465: 2: total-size count source
1630587465: 2: 0 0 Total of 0
1630587465: 2: ending time = 1630587465, elapsed since start = 0:00:01
Remove the fgetc
I got only one warning with memory not being freed.
1630587578: 1: Dumping Not-Freed Pointers Changed Since Start:
1630587578: 1: not freed: '0x7f939f4e0008|s1' (4096 bytes) from 'unknown'
1630587578: 1: total-size count source
1630587578: 1: 0 0 Total of 0
Remove the printf
then I got:
1630587655: 0: Dumping Not-Freed Pointers Changed Since Start:
1630587655: 0: memory table is empty
1630587655: 0: ending time = 1630587655, elapsed since start = 0:00:00
The gcc
version being used here is 9.3.0 and the dmalloc is 5.5.2 which comes with most latest Linux distros when install using their package manager.
NOTE
g++
.1630589888: 2: Dmalloc version '5.6.5' from 'http://dmalloc.com/'
1630589888: 2: flags = 0x403, logfile 'dmalloc.log'
1630589888: 2: interval = 0, addr = 0x0, seen # = 0, limit = 0
1630589888: 2: starting time = 1630589886
1630589888: 2: process pid = 11185
1630589888: 2: Dumping Chunk Statistics:
1630589888: 2: basic-block 4096 bytes, alignment 8 bytes
1630589888: 2: heap address range: 0x7ff82bd98000 to 0x7ff82bd9b000, 12288 bytes
1630589888: 2: user blocks: 1 blocks, 2048 bytes (16%)
1630589888: 2: admin blocks: 2 blocks, 8192 bytes (67%)
1630589888: 2: total blocks: 3 blocks, 12288 bytes
1630589888: 2: heap checked 0
1630589888: 2: alloc calls: malloc 2, calloc 0, realloc 0, free 0
1630589888: 2: alloc calls: recalloc 0, memalign 0, valloc 0
1630589888: 2: alloc calls: new 0, delete 0
1630589888: 2: current memory in use: 2048 bytes (2 pnts)
1630589888: 2: total memory allocated: 2048 bytes (2 pnts)
1630589888: 2: max in use at one time: 2048 bytes (2 pnts)
1630589888: 2: max alloced with 1 call: 1024 bytes
1630589888: 2: max unused memory space: 2048 bytes (50%)
1630589888: 2: top 10 allocations:
1630589888: 2: total-size count in-use-size count source
1630589888: 2: 0 0 0 0 Total of 0
1630589888: 2: Dumping Not-Freed Pointers Changed Since Start:
1630589888: 2: not freed: '0x7ff82bd9a008|s1' (1024 bytes) from 'unknown'
1630589888: 2: not freed: '0x7ff82bd9a808|s1' (1024 bytes) from 'unknown'
1630589888: 2: total-size count source
1630589888: 2: 0 0 Total of 0
1630589888: 2: ending time = 1630589888, elapsed since start = 0:00:02
i cannot find the test result file: logfile.
my compile cmd is:
gcc -DDMALLOC -DDMALLOC_FUNC_CHECK -ldmalloc -I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 -lmongoc-1.0 -lbson-1.0 test.c
can you help me?
thank you!
Copied from #23 . Thanks much to @aitap
Functions in append.c pass va_lists to other functions, expecting state modifications done by va_arg() in the callee to persist in the caller. Apparently this is not the case for mingw (where va_list could be just a char *), so loc_snprintf(setup, sizeof(setup), "debug=%#x,start=%s:%d", 0x400, loc_file, loc_line); crashes while trying to dereference 0x400 instead of loc_file.
gcc --version
gcc (Ubuntu 8.1.0-5ubuntu1~16.04) 8.1.0
make
rm -f arg_check.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c arg_check.c -o ./arg_check.o
In file included from /usr/include/string.h:630,
from arg_check.c:31:
dmalloc.h:482:7: error: expected identifier or ‘(’ before ‘extension’
char *strndup(const char *string, const DMALLOC_SIZE len);
^~~~~~~
Makefile:407: recipe for target 'arg_check.o' failed
make: *** [arg_check.o] Error 1
Hi, I maintain this package for Mageia and seem to be having problems finding the docs. Am I missing something or is the tarball missing something?
In the embeded system without MMU, it's very common that many memory regions exist, so It's will be very useful if dmalloc can support it. Actually, we have sucessfully ported dmalloc to a popular RTOS(https://github.com/apache/incubator-nuttx) which has a clean multiple heap interface(https://github.com/apache/incubator-nuttx/blob/master/include/nuttx/mm/mm.h):
void mm_initialize(FAR struct mm_heap_s *heap, FAR void *heap_start,
size_t heap_size);
void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
size_t heapsize);
FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size);
void mm_free(FAR struct mm_heap_s *heap, FAR void *mem);
FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
size_t size);
FAR void *mm_calloc(FAR struct mm_heap_s *heap, size_t n, size_t elem_size);
FAR void *mm_zalloc(FAR struct mm_heap_s *heap, size_t size);
FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
size_t size);
bool mm_heapmember(FAR struct mm_heap_s *heap, FAR void *mem);
FAR void *mm_brkaddr(FAR struct mm_heap_s *heap, int region);
FAR void *mm_sbrk(FAR struct mm_heap_s *heap, intptr_t incr,
uintptr_t maxbreak);
void mm_extend(FAR struct mm_heap_s *heap, FAR void *mem, size_t size,
int region);
int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info);
The idea is that:
extern
DMALLOC_PNT dmalloc_heap_malloc(dlmalloc_heap *heap, const char *file, const int line,
const DMALLOC_SIZE size, const int func_id,
const DMALLOC_SIZE alignment,
const int xalloc_b);
static dlmalloc_heap heap:
DMALLOC_PNT dmalloc_malloc(const char *file, const int line,
const DMALLOC_SIZE size, const int func_id,
const DMALLOC_SIZE alignment,
const int xalloc_b)
{
return dmalloc_heap_malloc(&heap, file, line, size, func_id, alignment, xalloc_b);
}
With this change install, it will be easy to replace dlmalloc in the embeded environment.
I have a Windows-only project that dmalloc could really help with. Currently, it seems that the only way to use dmalloc on Windows is to build it with Cygwin, since the only virtual memory APIs that dmalloc currently speaks are sbrk
and mmap
, and Windows has neither.
If you are interested in this, I could prepare a pull request modifying heap.c
to use VirtualAlloc
/ VirtualFree
in addition to mmap
/ munmap
, bringing me closer to my goal of cross-compiling dmalloc for Windows using something like ./configure --build=i686-linux-gnu --host=i686-w64-mingw32
. While lack of mmap
could be worked around using INTERNAL_MEMORY_SPACE
, it's not a good solution.
Greetings,
I would like to ask if the issue drok/ovpn#7 is known. It appears that when free(pnt=0x0) is called, dmalloc gets into an infinite recursive loop that eventually overflows the process stack.
I have absolutely no experience with dmalloc, so it's possible the error is in my usage; if so, I would appreciate any feedback.
As a first time user of dmalloc 5.5.2, I encountered the following "multiple definition" error while building the shared library target "installsl":
bc6:radu [Linux] /tmp/dmalloc
$ ./configure --prefix=/tmp/dmalloc-root/usr
[... success ...]
$ make install installsl
rm -f dmalloc.h dmalloc.h.t
cat ./dmalloc.h.1 dmalloc.h.2 ./dmalloc.h.3 > dmalloc.h.t
mv dmalloc.h.t dmalloc.h
./mkinstalldirs /tmp/dmalloc-root/usr/include
/usr/bin/install -c -m 644 dmalloc.h /tmp/dmalloc-root/usr/include
rm -f arg_check.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c arg_check.c -o ./arg_check.o
rm -f compat.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c compat.c -o ./compat.o
rm -f dmalloc_rand.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c dmalloc_rand.c -o ./dmalloc_rand.o
rm -f dmalloc_tab.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c dmalloc_tab.c -o ./dmalloc_tab.o
rm -f env.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c env.c -o ./env.o
rm -f heap.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c heap.c -o ./heap.o
rm -f chunk.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c chunk.c -o ./chunk.o
rm -f error.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c error.c -o ./error.o
rm -f malloc.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c malloc.c -o ./malloc.o
ar cr libdmalloc.a arg_check.o compat.o dmalloc_rand.o dmalloc_tab.o env.o heap.o chunk.o error.o malloc.o
ranlib libdmalloc.a
./mkinstalldirs /tmp/dmalloc-root/usr/lib
/usr/bin/install -c libdmalloc.a /tmp/dmalloc-root/usr/lib
ranlib /tmp/dmalloc-root/usr/lib/libdmalloc.a
Enter 'make installsl' to install libdmalloc.so in /tmp/dmalloc-root/usr/lib
Enter 'make installcxx' to install the C++ library
Enter 'make installth' to install thread library
rm -f dmalloc.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c dmalloc.c -o ./dmalloc.o
rm -f dmalloc_argv.o
gcc -g -O2 -DHAVE_STDARG_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_W32API_WINBASE_H=0 -DHAVE_W32API_WINDEF_H=0 -DHAVE_SYS_CYGWIN_H=0 -DHAVE_SIGNAL_H=1 -I. -I. -c dmalloc_argv.c -o ./dmalloc_argv.o
rm -f dmalloc
gcc -o aout dmalloc.o dmalloc_argv.o compat.o env.o \
-L.
mv aout dmalloc
./mkinstalldirs /tmp/dmalloc-root/usr/bin
/usr/bin/install -c dmalloc /tmp/dmalloc-root/usr/bin
Enter 'make installdocs' to install dmalloc.html dmalloc.texi dmalloc.pdf in /tmp/dmalloc-root/usr/share/doc/dmalloc
rm -f libdmalloc.so libdmalloc.so.t
ld -shared --whole-archive -soname libdmalloc.so -o libdmalloc.so.t libdmalloc.a arg_check.o compat.o dmalloc_rand.o dmalloc_tab.o env.o heap.o
arg_check.o: In function `_dmalloc_strlen':
/tmp/dmalloc/arg_check.c:446: multiple definition of `_dmalloc_strlen'
libdmalloc.a(arg_check.o):/tmp/dmalloc/arg_check.c:446: first defined here
arg_check.o: In function `_dmalloc_strtok':
/tmp/dmalloc/arg_check.c:669: multiple definition of `_dmalloc_strtok'
libdmalloc.a(arg_check.o):/tmp/dmalloc/arg_check.c:669: first defined here
arg_check.o: In function `_dmalloc_strstr':
/tmp/dmalloc/arg_check.c:650: multiple definition of `_dmalloc_strstr'
libdmalloc.a(arg_check.o):/tmp/dmalloc/arg_check.c:650: first defined here
To get around it, I had to make this change to Makefile.in, which allowed the installation:
diff --git a/Makefile.in b/Makefile.in
index f49c6f9..a60f139 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -302,7 +302,7 @@ shlib : $(BUILD_SL)
# via: http://256.com/gray/email.html
$(LIB_SL) : $(LIBRARY)
rm -f $@ [email protected]
- @shlinkargs@ $(LIBRARY) $(OBJS) $(NORMAL_OBJS)
+ @shlinkargs@ $(LIBRARY)
mv [email protected] $@
$(LIBRARY) : $(OBJS) $(NORMAL_OBJS)
@@ -315,7 +315,7 @@ $(LIB_TH) : $(OBJS) $(THREAD_OBJS)
$(LIB_TH_SL) : $(LIB_TH)
rm -f $@ [email protected]
- @shlinkargs@ $(LIB_TH) $(OBJS) $(THREAD_OBJS)
+ @shlinkargs@ $(LIB_TH)
mv [email protected] $@
$(LIB_CXX) : $(OBJS) $(NORMAL_OBJS) $(CXX_OBJS)
This may be related to #4 as the unit test that triggers that issue is linked against the shared library built with the patch above.
make installdocs returns:
make[2]: don't know how to make ./dmalloc.info. Stop
I think the issue is that there's a rule in Makefile.in for dmalloc.info via INFOFILE but not one for ./dmalloc.info.
In Makefile.in:
-installdocs : $(srcdir)/$(HTMLFILE) $(srcdir)/$(INFOFILE)
+installdocs : $(srcdir)/$(HTMLFILE) $(INFOFILE)
$(INFOFILE) : $(srcdir)/dmalloc.texi
rm -f $@ [email protected]
- makeinfo -o [email protected] --fill-column=100 --no-split $<
+ makeinfo -o [email protected] --fill-column=100 --no-split $(srcdir)/dmalloc.texi
fixes it for me.
BTW, DOCFILES specifies non-existent documentation files, and is only used in an echo statement.
dmalloc: critical error: could not extend heap 4096 more bytes
debug-malloc library: dumping program, fatal error
In the dmalloc-5.6.0 release, the installdocs target looks as follows:
installdocs :
the docs directory doesn't exist in the release tar. the html and texi file are in $(srcdir), though the pdf file is not.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.