Next: , Previous: Linking, Up: Frequently asked questions


J.4 Running

  1. I've just linked and run my program with the mpatrol library, but the resulting log file doesn't contain any useful information. Why does it not contain a list of all memory transactions or show any unfreed memory allocations?

    By default, the mpatrol library will only write a summary of library settings and statistics to the log file, and that will only occur on successful program termination (i.e. when exit() is called). If this does not appear then it is likely that your program (or some other library function) called abort() due to a fatal error. However, there are a multitude of different options that you can pass to the mpatrol library via the MPATROL_OPTIONS environment variable that will allow you to control what is logged and what is not. Note that the mpatrol command will always log all calls to allocate, reallocate and free memory by default.

  2. Why does my C++ program crash at program termination when it is linked with the mpatrol library and it appears to be doing nothing wrong?

    If your program contains file-scope objects whose constructors get called before main() and whose destructors get called after main() then it is likely that one of these destructors is allocating memory after the mpatrol library has terminated. This should already be resolved if you built the mpatrol library on a platform that supports `.init' and `.fini' sections or if you built it with the GNU compiler or a C++ compiler. However, in certain circumstances this may not work so you may wish to try terminating the mpatrol library by getting it to register itself with atexit() instead, which will hopefully resolve the problem. You can do this by rebuilding the mpatrol library with the MP_USE_ATEXIT preprocessor macro defined.

  3. I linked my program with the mpatrol library to trace all of its memory operations, such as memcpy() and memcmp(), but I get nothing in the log file. Why is this?

    On systems that do not support `.init' and `.fini' sections or are not gcc or C++ based then the memory operation functions will not automatically initialise the mpatrol library since on many systems the startup routines call them very early on. On such systems, if your program does not call any memory allocation functions to initialise the mpatrol library then you must explicitly call the __mp_init() function. All memory operation functions following that call with then be traced.

  4. Why does the USEDEBUG option not work for me?

    Firstly, you have to ensure that you have built the mpatrol library with support for the GNU BFD object file access library by compiling with the FORMAT=FORMAT_BFD preprocessor macro definition, or you are running on a Windows platform. Secondly, you have to ensure that you have compiled all relevant object files with debugging information enabled (usually by adding an option to the compiler command line), although the mpatrol library does not need to be compiled this way. The file and line number information will hopefully then appear in the log file for all symbols that have associated debugging information. If none of the above suggestions work, you may still be able to get this information with the mpsym command.

  5. Why does the mpatrol command ignore the current value of the MPATROL_OPTIONS environment variable?

    Because I would most likely get lots of bug reports or queries from people who had forgotten that they had set some options in the environment variable and had then not seen the expected behaviour from the options they specified to the mpatrol command. Recently, though, I've added the --read-env option so that this can be achieved.

  6. Why do I get an error from the dynamic linker about not being able to locate libiberty.so and libintl.so when I use the --dynamic option with the mpatrol command?

    The GNU libiberty and libintl libraries are required when the mpatrol library is built with support for the GNU BFD library but are unfortunately only available in archive form on many systems. See the section on the mpatrol command (see The mpatrol command) for information on how to get around this problem, either by embedding these libraries into the mpatrol library when you are building it, or by converting the archive forms of these libraries into their corresponding shared library versions.

  7. Why does the mpatrol library not read the symbols in my executable file on Windows platforms?

    If the mpatrol library was compiled with the FORMAT=FORMAT_IMGHLP preprocessor macro defined then you must ensure that you compile your files with debugging information enabled (using the -Z7 or -Zi options in Visual C++) and that you tell the linker that you wish to preserve the debugging information in the executable file (using the -debug and -pdb:none options in the Microsoft linker). Unfortunately, if you do not do this then the final executable file will not have a symbol table and so the mpatrol library cannot give symbolic stack tracebacks.

  8. Why do some mpatrol log file entries only contain a partial call stack rather than following the function call stack back to the call to main()?

    This could be because the mpatrol library was compiled with limited call stack traversal support via the MP_BUILTINSTACK_SUPPORT configuration macro. However, it could also mean that the mpatrol library encountered a corrupt frame pointer when traversing the call stack and had to terminate the recursion. The frame pointer must be preserved from function to function on most platforms, otherwise the stack cannot be traversed. See your compiler manual for further details.

  9. I am trying to use the mpatrol command to debug an executable file that was not originally compiled with the mpatrol library. However, even though it runs successfully, no mpatrol log file is produced. Why is this?

    First, check that you are passing the --dynamic option to the mpatrol command and, if necessary, the --threads option as well. If that doesn't work then check that the executable file has been dynamically linked; statically linked executables cannot be forced to use the mpatrol library. If it still doesn't work then it may be that the dynamic linker on your system doesn't have the ability to preload any shared libraries that have been specified in a special environment variable, in which case you can't use this feature.

  10. I am attempting to run a multithreaded C++ program with the mpatrol library on Linux. However, my program crashes before main() and the debugger shows that the failure is in __sigaction() which is called from __mp_initsignals(). Is the fault with the mpatrol library?

    There have been many reports of this problem and it turns out to be an issue with shared library dependencies. ELF shared libraries may contain initialisation functions that are executed before main(). However, sometimes the order in which these functions are executed is critical. In this case it is likely that the mpatrol and pthreads libraries are being initialised in the wrong order. You must ensure that -lpthread appears near the very end of the link line after all user libraries, and you must also ensure that none of the user libraries have a dependency on libpthread.so. You can verify this by running the ldd command on them.

  11. I know that there's a definite heap corruption problem in my program as it keeps crashing in unrelated code due to pointer corruption, and when I link with the mpatrol library it stops crashing. What can I do?

    Try as many of the relevant mpatrol run-time options as possible and make sure that you closely examine the mpatrol log file for warnings and errors — your problem may have been noticed by the mpatrol library but it may not have considered it a fatal error and continued execution. If this still doesn't show up anything then you can probably rest assured that you have a memory corruption problem but you may need to use a commercial product such as Purify to isolate it. If that fails then you'll just have to employ the traditional debugging method of single-stepping through your program in a debugger until something unusual or unexpected happens.

  12. If I link my program to version 1.0 of the mpatrol library then I cannot interrupt it using the keyboard, which I would normally be able to do without using mpatrol. Is this a bug?

    Not really, but it is undesirable behaviour in most cases, which is why it was removed in later releases of mpatrol and replaced with the SAFESIGNALS option. The reason that the program could not be interrupted using the keyboard was that mpatrol would ignore such signals when its library code was being executed, otherwise user-defined signal handlers that used malloc() and related functions would have the capability to cause lots of undesirable side effects. However, this does not normally happen, which is why the behaviour was moved to an option for those that needed it.

  13. Why does mpatrol not report an illegal memory access when it can be detected by a debugger?

    First of all, illegal memory accesses can only be detected on systems that support virtual memory, so that precludes AmigaOS and Netware. Secondly, it might be possible that something is overriding the illegal memory access handler that mpatrol sets up when it is first initialised. If your program, or an external library, sets up a signal handler that handles SIGBUS or SIGSEGV (or their equivalent on Windows platforms) then mpatrol will no longer be able to catch illegal memory accesses. You can either try to live with that, or you could try disabling the overriding handlers.

  14. How do I set a breakpoint on the malloc() function when it is implemented as a preprocessor macro in mpatrol.h?

    There are four different mpatrol interface functions which are used to allocate memory, duplicate strings, reallocate memory and deallocate memory. If you look in mpatrol.h you should be able to see the name of the function that will be called when the macro is invoked. The same goes for the memory operation functions.

  15. I've linked and run my program with mpatrol under UNIX and it uses a large amount of heap memory. However, it crashes near the end of execution and then proceeds to freeze up the whole system, sometimes requiring a reboot. What am I doing wrong?

    The most common possible explanation for this is that you are running your program with too much access to system resources. What is likely to be happening is that when your program crashes the system attempts to dump the entire process image to a core file for later debugging in a non-symbolic debugger. If the process has a huge heap then the core file is also going to be huge, thus resulting in a massive file that may lead to the system thrashing while it attempts to write it to the disk. Technically, the system has not frozen, but it is likely to take a long time to finish writing the file. The best solution involves setting your program's maximum core file size to a reasonable limit (or just zero), and also possibly limiting your program's maximum data segment size as well. These can be set from the shell but the exact details on how to do this differ between shells.

  16. Why does my program run so slowly after I link it with the mpatrol library?

    Normal malloc libraries are optimised for speed but will typically fall over at the slightest hint of an error. Debugging malloc libraries are written to provide as much debugging information as possible whilst performing a multitude of additional checks, which is why they may run much slower. However, you can control which checks are performed (and when) by using the MPATROL_OPTIONS environment variable. Performance may also be lost if you make lots of small memory allocations rather than fewer larger allocations, but that is mainly due to the overhead of storing the extra tracing details for each memory allocation.

  17. My program is written in C++ and is linked to the mpatrol library, but how do I go about demangling the C++ symbol names that are shown in the stack tracebacks in the resulting log file?

    Because there is no standard way of mangling C++ symbol names, various compilers and operating systems have taken different approaches to C++ name mangling, many of which differ significantly from the method suggested in The Annotated C++ Reference Manual by Margaret Ellis and Bjarne Stroustrup. However, most compilers come with a demangling tool which can be used in a command pipe to accept mangled names on its standard input file stream and demangle them on its standard output file stream, and so can be used to process the mpatrol log file. Note that mpatrol automatically demangles C++ symbol names on Windows platforms as Microsoft's name mangling is quite unreadable and would be hard to demangle using a command line tool.

  18. Why does my program not stop when the mpatrol library notices an error?

    The library was written to give as much information as possible and so sometimes, when a non-fatal error is discovered, the library will write the error message to the log file and continue in the hope of being able to uncover more errors during the execution of the program. This means that you should always check the number of warnings and errors given in the summary at the end of program execution, and then search backwards in the log file for `WARNING' or `ERROR'.

  19. I have linked my program with the mpatrol library on an Amiga or Netware machine, but when it runs it still crashes the entire system. Why is this?

    AmigaOS and Netware do not have virtual memory and so do not have memory protection turned on by default. This means that any rogue write to an erroneous address may actually overwrite the data of another process or perhaps even the operating system, thus bringing the entire machine down. There are several third-party system utilities available for the Amiga to add memory protection to machines with built-in MMUs, which can then be used in conjunction with mpatrol. I'm not sure about the availability of such software for Netware.

  20. I have built the mpatrol library with gcc on AmigaOS and have successfully linked it to my program. However, why are none of the options in the MPATROL_OPTIONS environment variable recognised when I run it?

    The getenv() function in the GNU C library is not compatible with the AmigaDOS SetEnv and GetEnv commands since it does not treat environment variables as files located in ENV: and is only compatible with software that uses the ixemul library. However, the env command that comes with most GNU software distributions allows you to set an environment variable that the GNU getenv() function can read when you are running in AmigaDOS.

  21. How do I suppress all diagnostic output from the mpatrol library?

    You can do this by setting the mpatrol log file to be your system's bit bucket, which is /dev/null on UNIX platforms and NIL: on AmigaOS. There doesn't appear to be an equivalent way to do this on Windows or Netware.