logo_kerberos.gif

Difference between revisions of "Debugging tips"

From K5Wiki
Jump to: navigation, search
(Using gcov for code coverage measurements)
 
(10 intermediate revisions by 2 users not shown)
Line 16: Line 16:
 
C++ code uses CXXFLAGS instead of CFLAGS. There isn't a lot of C++ code in the Unix build, but if you do run into a need to debug what there is, be sure to override CXXFLAGS as well as CFLAGS.
 
C++ code uses CXXFLAGS instead of CFLAGS. There isn't a lot of C++ code in the Unix build, but if you do run into a need to debug what there is, be sure to override CXXFLAGS as well as CFLAGS.
   
On Linux and perhaps other Unix variants, programs built with run-path options will consult the run path before LD_LIBRARY_PATH. As a result, libraries from the install prefix will take precedence over libraries in the build tree. This is particularly important to know when running the test suite. To work around this issue, you can "make install" before "make check", or you can configure the tree to build without run-path options:
+
On some platforms, programs built with run-path options will consult the run path before LD_LIBRARY_PATH. (This is less of a concern than it used to be because we now build with -Wl,--enable-new-dtags on Linux and FreeBSD, which causes the generated binaries to prefer LD_LIBRARY_PATH to the run path.) On these platforms, libraries from the install prefix will take precedence over libraries in the build tree. This is particularly important to know when running the test suite. To work around this issue, you can "make install" before "make check", or you can configure the tree to build without run-path options:
   
 
.../configure --disable-rpath
 
.../configure --disable-rpath
Line 22: Line 22:
 
A tree built this way may not be as useful when installed (since the binaries won't know how to find the libraries), but is more convenient for running programs out of the build tree. Note that plugins will still be loaded from the install prefix by default. The test suite overrides the plugin paths using special krb5.conf directives; if you are running a program by hand from the build tree and it uses plugins, you must either do the same overriding or run "make install" before running the program.
 
A tree built this way may not be as useful when installed (since the binaries won't know how to find the libraries), but is more convenient for running programs out of the build tree. Note that plugins will still be loaded from the install prefix by default. The test suite overrides the plugin paths using special krb5.conf directives; if you are running a program by hand from the build tree and it uses plugins, you must either do the same overriding or run "make install" before running the program.
   
If you are using certain kinds of instrumentation (such as gcov), you might need to do a build with static instead of shared libraries. You can do this with the --enable-static-only configuration flag. This flag will cause in-tree KDB plugins to be linked statically to the KDB library instead of loaded dynamically. At the moment, other kinds of plugins (such as preauth plugins) simply won't function.
+
If you are using certain kinds of instrumentation (such as gcov), you might need to do a build with static instead of shared libraries. You can do this with the --enable-static --disable-shared configuration flags. This flag will cause in-tree KDB plugins to be linked statically to the KDB library instead of loaded dynamically. At the moment, other kinds of plugins (such as preauth plugins) simply won't function.
  +
  +
==Trace Logging==
  +
  +
Even with a regular production build (for krb5 1.9 or trunk code after 2010-06-07), you can display trace events by setting the KRB5_TRACE environment variable to a filename. For example, try "env KRB5_TRACE=/dev/stdout kinit" to see some behind-the-scenes information about getting initial credentials. The KRB5_TRACE environment variable will not work for secure contexts, such as those created by ksu or login systems.
   
 
==Compile-Time Defines==
 
==Compile-Time Defines==
Line 34: Line 34:
 
make CPPFLAGS=-DFLAGNAME
 
make CPPFLAGS=-DFLAGNAME
   
===DEBUG_ERROR_LOCATIONS===
 
  +
=== -DDEBUG ===
  +
  +
Running
  +
  +
make CPPFLAGS=-DDEBUG
  +
  +
from the top of the build tree or
  +
  +
.../configure CPPFLAGS=-DDEBUG
  +
  +
is not recommended. Some code under <code>-DDEBUG</code> will not compile or link successfully. It is better to run
  +
  +
make CPPFLAGS=-DDEBUG
   
The DEBUG_ERROR_LOCATIONS flag causes verbose error messages generated from the krb5 libraries to include file and line number information. It can be useful if you're having trouble tracking down where an error message is generated. It will not work in cases where an error code is generated with no call to krb5_set_error_message or krb5int_set_error; in that case you will have to track it down the slow way with gdb or whatever. If you are seeing an error with no corresponding krb5_set_error_message_call, consider whether the error case is "likely" and perhaps add a krb5_set_error_message to make it clearer what is going on.
 
  +
in a single subdirectory containing the code of interest.
   
 
==Debugging the KDC==
 
==Debugging the KDC==
Line 44: Line 56:
 
==Using gcov for code coverage measurements==
 
==Using gcov for code coverage measurements==
   
gcov is a gcc-based tool for computing code coverage. To use it with the krb5 tree:
 
  +
gcov is a gcc-based tool for computing code coverage. It can be used to determine the code coverage of the test suite, or to aid in debugging by showing what areas of code are executed during a manual test. If you are running an older operating system release, you may need a newer version of gcc in order to use gcov with shared libraries.
   
# Do a build with --enable-static-only, since gcov does not work with shared libraries.
 
 
* Configure with CFLAGS="-g --coverage" LDFLAGS="--coverage". Building with these flags will create .gcno files in your build tree.
# Compile with:
 
  +
* Run whatever programs you want to compute coverage of. Running programs will create .gcda files in your build tree.
make CFLAGS="-g -fprofile-arcs -ftest-coverage" LDFLAGS="-fprofile-arcs -ftest-coverage"
 
 
* cd into a subdirectory and run "gcov -f filename.c -o filename.so.gcov" to see the code coverage of that source file. (If the build directory is not the source directory, specify the full path to the source file.) gcov will display the percentage coverage of each function in its output, and will also create filename.c.gcov showing the number of times each line of code was executed. Note that static inline functions in our header files will be reported in each source file which includes those headers, artificially reducing the apparent coverage.
Building with these flags will create .gcno files in your build tree.
 
  +
* Note that coverage data is only written when a program exits normally. If the program exits due to an unhandled signal, coverage information from that run will be lost.
# Run whatever programs you want to compute coverage of. If you are running the full test suite, specify the same CFLAGS and LDFLAGS options to make check as you did for make, as test programs are generally not built as part of "make all". Running programs will create .gcda files in your build tree. If you are running the krb-root tests, you must pre-create some .gcda files to avoid them being created as root and being unwritable by you; simplest is probably to run:
 
find . -name "*.gcno" | sed -e 's/gcno$/gcda/' | xargs touch
 
# cd into a subdirectory and run "gcov -f filename.c" to see the code coverage of that source file. gcov will display the percentage coverage of each function in its output, and will also create filename.c.gcov showing the number of times each line of code was executed. You can process this output any way you wish. Note that static inline functions in our header files will be reported in each source file which includes those headers; you may want to filter those out to avoid the resulting deflation in apparent overall coverage.
 

Latest revision as of 17:22, 14 April 2020

This page documents krb5-specific techniques which may help debug problems. Feel free to add additional techniques.

As always, the basic tools are helpful: debuggers like gdb or dbx, system call tracing tools like strace or truss, shared library tracing tools like ltrace or sotruss, and memory debugging tools like valgrind or Purify.

Building for Testing or Debugging

By default, krb5 will build with optimization, making it difficult to debug. You can change this at configure time using the CFLAGS variable:

 .../configure CFLAGS=-g

or at build time:

 make CFLAGS=-g

C++ code uses CXXFLAGS instead of CFLAGS. There isn't a lot of C++ code in the Unix build, but if you do run into a need to debug what there is, be sure to override CXXFLAGS as well as CFLAGS.

On some platforms, programs built with run-path options will consult the run path before LD_LIBRARY_PATH. (This is less of a concern than it used to be because we now build with -Wl,--enable-new-dtags on Linux and FreeBSD, which causes the generated binaries to prefer LD_LIBRARY_PATH to the run path.) On these platforms, libraries from the install prefix will take precedence over libraries in the build tree. This is particularly important to know when running the test suite. To work around this issue, you can "make install" before "make check", or you can configure the tree to build without run-path options:

 .../configure --disable-rpath

A tree built this way may not be as useful when installed (since the binaries won't know how to find the libraries), but is more convenient for running programs out of the build tree. Note that plugins will still be loaded from the install prefix by default. The test suite overrides the plugin paths using special krb5.conf directives; if you are running a program by hand from the build tree and it uses plugins, you must either do the same overriding or run "make install" before running the program.

If you are using certain kinds of instrumentation (such as gcov), you might need to do a build with static instead of shared libraries. You can do this with the --enable-static --disable-shared configuration flags. This flag will cause in-tree KDB plugins to be linked statically to the KDB library instead of loaded dynamically. At the moment, other kinds of plugins (such as preauth plugins) simply won't function.

Trace Logging

Even with a regular production build (for krb5 1.9 or trunk code after 2010-06-07), you can display trace events by setting the KRB5_TRACE environment variable to a filename. For example, try "env KRB5_TRACE=/dev/stdout kinit" to see some behind-the-scenes information about getting initial credentials. The KRB5_TRACE environment variable will not work for secure contexts, such as those created by ksu or login systems.

Compile-Time Defines

You can specify extra defined symbols for the build at configure time like so:

 .../configure CPPFLAGS=-DFLAGNAME

or at build time:

 make CPPFLAGS=-DFLAGNAME

-DDEBUG

Running

make CPPFLAGS=-DDEBUG

from the top of the build tree or

.../configure CPPFLAGS=-DDEBUG

is not recommended. Some code under -DDEBUG will not compile or link successfully. It is better to run

make CPPFLAGS=-DDEBUG

in a single subdirectory containing the code of interest.

Debugging the KDC

krb5kdc can be run with the -n flag to prevent it from backgrounding itself, allowing you to set breakpoints before it starts. Alternatively, you can attach to the process after it forks. The process_as_req and process_tgs_req functions are the entry points to handling client requests.

Using gcov for code coverage measurements

gcov is a gcc-based tool for computing code coverage. It can be used to determine the code coverage of the test suite, or to aid in debugging by showing what areas of code are executed during a manual test. If you are running an older operating system release, you may need a newer version of gcc in order to use gcov with shared libraries.

  • Configure with CFLAGS="-g --coverage" LDFLAGS="--coverage". Building with these flags will create .gcno files in your build tree.
  • Run whatever programs you want to compute coverage of. Running programs will create .gcda files in your build tree.
  • cd into a subdirectory and run "gcov -f filename.c -o filename.so.gcov" to see the code coverage of that source file. (If the build directory is not the source directory, specify the full path to the source file.) gcov will display the percentage coverage of each function in its output, and will also create filename.c.gcov showing the number of times each line of code was executed. Note that static inline functions in our header files will be reported in each source file which includes those headers, artificially reducing the apparent coverage.
  • Note that coverage data is only written when a program exits normally. If the program exits due to an unhandled signal, coverage information from that run will be lost.