|
|
Dmalloc Tutorial: 3.11 Debugging Memory in a Server or Cgi-Bin Process
3.11 Debugging Memory in a Server or Cgi-Bin Process
There are some specified challenges when trying to debug allocations
in processes which do not startup, run, and then shutdown. Server
processes (often called daemons) are those that are started (often at
system boot time) and run perpetually. Other processes which are
difficult to debug are CGI programs which are spawned by web servers
or when you want to start debugging inside of a child process.
- Build your server or cgi-bin program with the dmalloc library
like any other program. See section Getting Started with the Library.
- Add code into your program to enable the library flags to
perform the memory checks that you require. Since these programs
often do not run from the command line, you cannot use the dmalloc
utility program and modify the process environment. See section Dmalloc Utility Program. The library provides a couple of functions to set the
debugging flags when a program is running.
- To set the memory debugging flags, use the
dmalloc_debug_setup function which takes a string in the same
format of the `DMALLOC_OPTIONS' environmental variable.
See section Environment Variable Name and Features. Use the dmalloc utility with the
-n no-changes argument to see the appropriate settings for the
`DMALLOC_OPTIONS' environmental variable.
| | > dmalloc -n -l logfile high
Outputed:
DMALLOC_OPTIONS=debug=0x4f4ed03,log=logfile
export DMALLOC_OPTIONS
|
So if you want to turn on high debugging and log to the file
`logfile' then you would copy the above `DMALLOC_OPTIONS'
value into a call to dmalloc_debug_setup. Notice that I have
surrounded the dmalloc code with an #ifdef DMALLOC so you'll
have to compile using the -DDMALLOC flag.
| | main()
{
#ifdef DMALLOC
/* set the 'high' flags */
dmalloc_debug_setup("debug=0x4f47d03,log=logfile");
#endif
…
}
|
Please note that the dmalloc_debug_setup function does
not know about high, low, or other debug tokens but
needs the actual flag values.
- For earlier versions of the library (before 5.0.0) without
dmalloc_debug_setup, the dmalloc_debug function is
available to set the flags directly, but it cannot adjust the logfile
name and the other environment settings. You can use the dmalloc
utility program to see what the numerical equivalent of the high
token.
| | > dmalloc -n high
Outputed:
DMALLOC_OPTIONS=debug=0x4f4ed03
export DMALLOC_OPTIONS
|
You can then take the 0x4f4ed03 hexadecimal number and call
dmalloc_debug with that number.
| | main()
{
#ifdef DMALLOC
/* set the 'high' flags */
dmalloc_debug(0x4f4ed03);
#endif
…
}
|
- Even with the settings enabled, you may have problems getting
the logfile to be written if your program is running as `nobody'
or another user without permissions for security reasons. This is
especially true for cgi-bin programs. In this case you should specify
a full path to your malloc logfile in a world writable directory
(ex.
dmalloc_debug_setup("debug=0x4f47d03,log=/var/tmp/malloc");).
Watch for programs which change into other directories and which may
cause logfiles specified as relative or local paths to be dropped in
other locations. You may always want to use a full path logfile.
- Once you have your settings enabled and your log is being
generated, you may now want to check out how your process is doing in
terms of unfreed memory. Since it is not shutting down, the automatic
unfreed log entries are not being dropped to the logfile. By using
the
dmalloc_mark and dmalloc_log_changed functions, you
can set a mark point at a certain place inside of your program, and
then later see whether there are any unfreed pointers since the mark.
| | main()
{
#ifdef DMALLOC
/* set the 'high' flags */
dmalloc_debug_setup("debug=0x4f47d03,log=logfile");
#endif
while (1) {
/* accept a connection from a client */
accept_connection();
while (1) {
#ifdef DMALLOC
unsigned long mark;
/* get the current dmalloc position */
mark = dmalloc_mark() ;
#endif
/* process the connection */
if (process_connection() != PROCESS_OK) {
break;
}
#ifdef DMALLOC
/* log unfreed pointers that have been added to the heap since mark */
dmalloc_log_changed(mark,
1 /* log unfreed pointers */,
0 /* do not log freed pointers */,
1 /* log individual pointers otherwise a summary */);
#endif
}
/* close the connection with the client */
close_connection();
}
…
}
|
Usually you would set the mark after the initializations and before
each transaction is processed. Then for each transaction you can use
dmalloc_log_changed to show the unfreed memory.
See section Additional Non-standard Routines.
- You can also use the
dmalloc_log_stats function to dump
general information about the heap. Also, remember that you can use
the dmalloc_message and dmalloc_vmessage routines to
annotate the dmalloc logfile with details to help you debug memory
problems. See section Additional Non-standard Routines.
This document was generated by Gray Watson on May, 16 2007 using texi2html 1.76.
This work is licensed by Gray Watson
under the Creative Commons
Attribution-Share Alike 3.0 License.
This page should be W3C Valid
XHTML and should work with most browsers.
|