Dmalloc Logo
Home

Documentation
Downloads
Forums
Releases

Search this site:

Donations:
If dmalloc has saved you or your company time or money, please use your credit-card or PayPal account to donate to the cause.

Dmalloc Tutorial: 3.12 Debugging Memory in a Server or Cgi-Bin Process
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.12 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.

  1. Build your server or cgi-bin program with the dmalloc library like any other program. See section Getting Started with the Library.
  2. 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.
  3. 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.

  4. 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
      …
    }
    
  5. 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.
  6. 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 each pnt otherwise 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.

  7. 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.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]

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.