|
By Maxim Kartashev, Sun Microsystems, April 11, 2006
|
|
|
The Sun Studio debugger, dbx, will complain when it can't find all the debug information it needs for your program. This article will show you the error messages that might appear, explain what could go wrong, and suggest how to fix things.
»
Read Russian version
Errors you might see
Here are some typical error messages that you might encounter while
using the Sun Studio debugger, dbx:
(dbx) stop in foo dbx: warning: 'foo' has no debugger info -- will trigger on first instruction ----- (dbx) stop at b.c:5 dbx: no executable code at line "b.c":5 ----- dbx: warning: can't find file "/.../a.o" dbx: warning: see `help finding-files' ----- (dbx) stop at a.c:5 dbx: cannot find object file corresponding to "a.c" ----- (dbx) list foo dbx: no source lines for "foo"
Possible causes
- Object files might have been compiled
without
-g
- Check your makefiles and/or build log to see if the
-g
compiler option has been specified. See also how to
determine if your a.out/.so/.o has debug info in the
section below.
- Load objects might have been
stripped
- Check your makefiles to see if
a.out/.so was
stripped after being built and eliminate strip command.
- Object files might not be where dbx
expects them to be
- They may have been moved since the loadobject was created, or
the directory might be mounted at a different location. In this case,
pathmap
dbx command should help. See how to use pathmap
below. This problem only affects stabs information, not dwarf. See below for more information.
- A shared library might not be loaded
yet
-
If you are trying to debug a shared library (.so),
it might be that it has not been loaded yet. This can be determined
with loadobject -list | grep <your library>. You
can often just run your program once through quickly to cause the
libraries to be loaded, and then re-run it to debug it. This will have
the side effect of loading all the libraries. You could also load the
library explicitly using the dbx command loadobject -load
<your .so path>.
After it is loaded, you should be able to debug this shared library.
Note: libraries linked in with -l will be loaded
automatically by dbx, but libraries loading using the dlopen function
call will not be seen by dbx until the program is run.
How to determine what went wrong
In the case where you know the name of the function you wish to
debug (let it be foo(), for examle), issue
(dbx) whereis foo
If you see something like
function: `a.out`#__1cDfoo6Fipc_i_ [non -g,
demangles to: foo(int,char*)]
(note absence of source file name after a.out) you can be
sure that file containing this function was compiled without debug
info or has been stripped. In order to be able to debug foo(),
you need to recompile it with -g and eliminate any kind
of strip commands from the build script.
The following output (note presence of a.c after a.out)
function: `a.out`a.c`#__1cDbar6Fi_pc_
[non -g, demangles to: bar(int)]
means that object file containing this function (as well as debug
information) was not found by dbx. Use the pathmap
command (see below) to tell dbx where to find it.
And finally, no output means that dbx does not see any symbol with
the specified name. If you are sure that it exists, it means that the
function resides in a library that has not been loaded yet. Use the loadobject
-load command to load it (see
above).
If you know the object file name that contains functions you wish
to debug, you can take advantage of module -v
dbx command.
Issue module -v <your .o file> and
check its output. If dbx says that the object file is not available,
then it was compiled without -g.
If it prints the original (expected) .o file path and
also prints that it cannot be found, then .o file has
been moved from its original (build) location. Make sure this .o
file exists and use pathmap in this case.
And if dbx prints "Can't find module ...",
then either your loadobject does not have debug info or the object
file you are looking for does not belong to any of the loaded
loadobjects (i.e. executables or shared libraries). Use loadobject
-list to see which shared libraries are currently
loaded.
How to determine if your a.out/.so/.o has debug info
The Sun Studio compilers can generate debug information in either
stabs or dwarf format. (See below) In Sun Studio
11, the C compiler will generate dwarf by default, and the C++ and
Fortran compilers will generate stabs. In a future release, all the
compilers will eventually migrate to using dwarf by default.
When you are in doubt whether an object file has debug info or
not, use the SunStudio dwarfdump/dumpstabs utilities
(one per debug info type - dwarf and stabs respectively). Both
commands are suitable for any ELF file (a.out/.so/.o).
The main problem here is that absence of one type of debug info does
not mean a thing -- you have to have a complete picture before you
can be sure about debug info presence.
Try executing dwarfdump:
$ dwarfdump -l
<a.out/.so/.o>
If it prints "No DWARF information present in a.out",
then either a.out is compiled with stabs or without debug info.
If dwarfdump prints a .debug_line
section, check to see if it contains any line info. If it is empty,
then debug info type for a.out is definitely dwarf, but
debug information is absent (it is the case when -xdebugformat=dwarf
has been specified, but -g has not). And if .debug_line
is not empty, dwarf debug info is present.
If no dwarf debug info is found, try
$ dumpstabs -s
<a.out/.so/.o>
For a file without debug info, the Index
Stab Table that is printed with this command is either absent
or contains a small number of entries (three). If there's more (tens,
hundreds, thousands, etc) - this file has stabs debug info.
How to use pathmap to point to your object
files
If you debug your program from different location (NFS mounts or
suchlike) or .o files have been moved from their
original (build) locations, dbx is unable to find them because index
debug information refers to the files by their full pathnames.
To workaround this problem, use the pathmap
command. Suppose your files were built in /home/me/program/
directory, but you are debugging the program from a different machine
and accessing the files via NFS using /net/machine/myprogram
mount point.
In this case you can issue
(dbx) pathmap
/home/me/program
/net/machine/myprogram
and dbx translates all references to old location
(/home/me/program) to new location
(/net/machine/myprogram).
More information
The dbx command help finding-files provides a good
description of possible problems and solutions
- The following Sun Studio compiler options are related to debug
info generation, and apply to C, C++, and Fortran compilers:
-
-g - generate debug info. Even without this
option, a small amount of stabs or dwarf information will be put into
the .o file.
-xs - this option causes all the debug
information to be generated into the .o files in such a way that it
will end up collected into the a.out or shared library when it is
linked. This has little impact on dbx performance or the run-time
performance of the program, but it does take more disk space. Only
useful when debug info type is stabs.
-xdebugformat=[stabs|dwarf] - specify debug info
format to be stabs or dwarf
- Some useful dbx commands are:
-
module
-
modules
-
pathmap
-
loadobject
-
(use help <command> in dbx to find out
more).
- Some other useful resources are:
- stabs
- Stabs is older debug information format; it is still generated
by Sun Studio 11 C++ and Fortran compilers by default, though. More
information can be found here: http://blogs.sun.com/roller/page/quenelle?entry=the_story_of_lazy_stabs
- dwarf
- DWARF (Debug With Arbitrary Record Format) is newer and
extensible debug format, now supported by SunStuio compilers; later g++
and Sun Studio C compiler generate dwarf by default.
|