Checker(3)

NAME
Checker - robust malloc and garbage collector.

SYNOPSIS
#include <malloc.h>
__ptr_t malloc(size_t __size);
void free(__ptr_t __ptr);
__ptr_t realloc(__ptr_t __ptr, size_t __size);
__ptr_t calloc(size_t __nmemb, size_t __size);
__ptr_t memalign(size_t __alignment, size_t __size);
__ptr_t valloc(size_t __size);
void chkr_garbage_detector();
void chkr_evol_detector();
void __chkr_dump_frag();
void __chkr_dump_free();
void __chkr_dump_block(const size_t block);
void __chkr_check_intern();
void __chkr_show_busy();
extern int chkr_errno;
extern int chkr_show_err_flag;
extern const char * const chkr_errlist[];
void (*__chkr_trap) (const int header, const char *, ...);

INTRODUCTION
Checker is a robust malloc, free, etc, with a garbage collector. So, it must be used in place of your standard malloc. It can be also a simple malloc package, according to the option while compiling. Using Checker is simple: compile it, and link it with your program. If your program has no memory error, you can't see the difference. but if your program handle incorrectly malloc, free, realloc Checker will immediately warn you. Checker warns you when:

o You call free or realloc before malloc

o You try to free a free zone

o You call free with a different address

Futhermore, Checker malloc try to be the most secure as possible: If you alloc a zone, then free it, alloc another zone of the same size, refreeing the first zone produce, in some case, a warning.
Using the garbage detector is non-automatic: you must call it. This can be done easily with your debuger.
Checker will be a GNU implementaion of Purify(tm).

DESCRIPTION
__ptr_t is defined as void * on ANSI-C compiler and as char * on K&R compiler.

size_t is defined by sys/types.h often as long

malloc() alloc __size bytes of memory. If no memory is available, malloc returns NULL otherwise, it returns a pointer at the first bytes of allocated memory. You may not suppose that malloc allocates more memory than __size bytes. With some malloc, that is right, but with Checker, that is false.
malloc(0) returns NULL

free() frees memory allocated by malloc()

realloc() change the size of a zone allocated by malloc. It returns a pointer at the new zone, which can be different from the old one. In this case, realloc copies the memory from the old zone.
If __ptr is NULL the behavior of realloc is the same than malloc
If __size is 0, realloc free the memory and returns NULL

realloc() allocates nmemb elements of __size bytes. The zone is initialized with 0.
realloc() is often used like this: ptr = (int*)realloc(n, sizeof(int));

memalign allocates __size bytes. The address of the zone is a multiple of __alignment The memory can be freed by free()

valloc() allocates __size bytes. The zone begin on a page.

chkr_garbage_detector() shows all leaks found in memory. This function can be call at any time.

chkr_evol_detector() shows all new leaks found in memory, after the last detection. __chkr_dump_frag() displays the fragment table. Useful only when debugging.

__chkr_dump_free() displays all free zone. Useful only when debugging.

__chkr_dump_block() displays the state of the block block. Useful only when debugging.

__chkr_check_intern() perfoms a check of internal tables and displays errors. This function doesn't check features better than CHECKER level. Not really useful for the final user.

__chkr_show_busy() shows all busy block. Usefuk only when debugging.

chkr_errno contains the error number. Errors can appear while calling free, malloc ... Because these function doesn't return anything (e.g. free ) or the return value can't help the user.

chkr_show_err_flag is a boolean value. When it is different from NULL Checker is allowed to display messages while an error occurs.

chkr_errlist[] contains strings describing each error.

(*__chkr_trap)() is a pointer at a function used by Checker to print all message. So you can redefine it. It uses the same format that printf except the first argument.
header is a boolean value, which tell if a header must be print. The header can inform the user that the following output is from Checker and not from the program.

USAGE
Suppose you want to use foo.o (it can be a list of object files) with Checker. You have just to link:
cc foo.o -o foo -lchecker -lyour_library -static
That's all.

Using the garbage collector is a little more difficult. You must run your program under a debugger, such as gdb
$ gdb foo
(gdb) run
Your program is running and you interrupt it with ^C
(gdb) call chkr_evol_detector()
or
(gdb) call chkr_garbage_collector()

OUTPUT MESSAGE
All message are printed with the hook-function __chkr_trap()
A warning is: (the first tab isn't displayed)
        From mallocdebug:
                Try to free a free block        <- warning message
        From mallocdebug:
                Stack frames are:               <- where the error occurs
                 pc=0x0000045d in main() at try.c:97
                 pc=0x0000002a in _entry() at /usr/lib/crt0.o:0
                    ^               ^             ^           ^
the instruction     |               |             |           |
  pointer  ---------|               |             |           |
function name ----------------------|             |           |
file where the function is written ---------------|           |
line where the error occurs ----------------------------------|
If function name or file name is "Unknown", Checker can't known it or them. If line number is 0, Checker can't known it. So, informations can be insuffisant because:

o Symbol table doesn't exist ( programm striped, linked with ld -s)

o Checker can't find the full path of the program: either the
    argv[0] is bad, or the file isn't accessible

o Symbol table isn't full: for having line number, you must compile
    file with -g

Only the pc value is sure. In this example, free was called two time. This is made by a program such as
main()
{
 char *addr;
 addr = (char*)malloc(10);
 free(addr);
 free(addr); /* Here a warning is generated */
}
From the stack frames, we know that the program begins with _entry(), defined in /usr/lib/crt0.o, _entry() calls main(), which is defined in the try.c file, and the second free() is made at line 97. Note that the file name is often a .c file, without the full path. If the .c file is unknown, Checker shows the .o file.

Checker implements a garbage detectors, which can be called in the program or by a debuger, such as gdb
The garbage detector displays all the family of memory leaks (or leaks), with the functions which called malloc.
An example of display is: (The first tab has been added)
        From mallocdebug:
                There are 2 leaks
                Leaks use 32560 bytes (31 Kb) / 116 Kb.
                So, 27.41% of the memory is lost.
        From mallocdebug:
                Checker found 20 * 128 bytes.
                 pc=0x000021c0 in malloc() at malloc.c:410
                 pc=0x000000ce in multiple_alloc() at try_detector.c:23
                 pc=0x000002df in main() at try_detector.c:63
                 pc=0x0000002a in _entry() at /usr/lib/crt0.o:0
        From mallocdebug:
                Checker found 5 * 6000 bytes.
                 pc=0x000021c0 in malloc() at malloc.c:410
                 pc=0x000000ce in multiple_alloc() at try_detector.c:23
                 pc=0x000002ee in main() at try_detector.c:64
                 pc=0x0000002a in _entry() at /usr/lib/crt0.o:0
Informations are rather obvious. When you read " Garbages found 20 * 128 bytes.", this means that there are 20 leaks of 128 bytes. Those 20 leaks have been allocated by the same way.

AUTHOR
Tristan Gingold

SEE ALSO
getpagesize(2), brk(2), sbrk(2), morecore(3), printf(3).

BUGS
Checker works fully only on linux. You must compile your program with statis library, because the shared library defined another data segment, unknown to Checker: it can know the begin but not the end.
Checker must be linked with object file that use the frame pointer. So don't compile your sources (or libraries) with -fomit-frane-pointer

COPYING
Copyright (c) 1993 Tristan Gingold

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be included in translations approved by the Free Software Foundation instead of in the original English.