Tru64 UNIX
Ladebug Debugger Manual


Previous Contents Index


Chapter 13
Debugging Shared Libraries

You can debug shared libraries if the library was compiled and linked with the option that makes symbol table information available to the debugger. For more information about shared libraries and linking programs to shared libraries, and compiling and linking programs and libraries for debugging, see your compiler documentation.

Loadable drivers can be considered a form of shared libraries, and can be debugged. For information, see Chapter 17 on kernel debugging.

You can debug shared libraries using the same techniques you use to debug any program function. The scope and visibility rules for debugging programs apply to debugging shared libraries.

You can call functions in shared libraries that do not have debugging information available.

For more information on the Ladebug commands mentioned in this chapter, see Part 5.

13.1 Controlling the Reading of Symbols for Shared Libraries

In general, build your images with symbol tables. You cannot set symbolic breakpoints to stop execution in or see the source code of shared libraries that do not have symbol table information available for the debugger.

By default, symbol table information is read into the debugger for all the shared libraries that are loaded, whether loaded at startup of the application or loaded dynamically by the application at run time.

For less bulky images, you can strip out symbol table information with the UNIX command ostrip (for information, see the ostrip(1) reference page). You can also use the following debugger commands to control symbols:


Chapter 14
Working with Limited Debugging Information

Depending on the options you use when compiling and linking your program, the debugging information available in your program's executable file may range from full to nonexistent. Programs that include shared libraries or other code modules may contain limited debugging information regardless of the compile options you use. Ladebug supports the debugging of programs that do not contain complete debugging information.

This chapter describes how to use Ladebug to debug a program containing limited debugging information. It provides examples and discusses some of the limitations you may experience. There are many scenarios under which a program can be compiled and linked---discussing each is beyond the scope of this chapter.

14.1 How Ladebug Works with Limited Debugging Information

Some compilers provide variants of the debug flag that provide different levels of debugging information and optimization. Depending on the options you use when compiling and linking your program, the debugging information available in the program's executable file may range from full to nonexistent. Programs that include shared libraries or other code modules may contain limited debugging information regardless of the compile options you use. Ladebug uses whatever information is available during a debugging session.

For example, with full debugging information, Ladebug can set breakpoints on procedures and functions; it recognizes routine names and knows parameters and values; it can display source code, knows the source file name, and can provide line numbers.

When encountering limited debugging information, Ladebug attempts to set breakpoints by making assumptions from the available information. See Section 14.2 for sample sessions in which you debug programs with limited information.

If no debugging information is available in the program's executable file, Ladebug allows for machine-level debugging. (See Chapter 15 for information on machine-level debugging.)

The following are some examples of compile and link options that are likely to produce limited debugging information:

Note

For the most up-to-date information on compiler and linker options and defaults, see the manual reference page for your particular language compiler and operating system release.

14.2 Example Debugging Sessions

The following sections compare Ladebug's ability to debug programs containing full or limited debugging information in the program's symbol table. Each example is provided in two forms:

  1. Compiled and linked with -g2 (full debugging information)
  2. Compiled and linked in such a way to produce limited debugging information

As a sample program is analyzed, you will first see the output based on full debugging information, which is then compared to the output where some of the debugging information is missing.

The examples provided are for illustration only and do not cover all of the conditions you may encounter. Use these example to help understand what may be happening when you debug your own programs and modules that contain less than full debugging information.

Note

If you encounter difficulty debugging your program, the best solution is to recompile and relink with the -g2 flag.

Sample sessions are presented as follows:

14.2.1 Example C++ Program Linked with -x

This section presents a sample debugging session on a C++ program containing full symbolic debugging information, then the same program compiled with -g2 and linked with -x. In the second form of the example program, -x strips all symbolic debugging information except for procedure and file information. The operating system is DIGITAL UNIX 5.0.

14.2.1.1 Setting Breakpoints

If your executable file contains full symbolic debugging information, Ladebug can set a breakpoint at various levels, as shown in Example 14-1.

Example 14-1 Setting Breakpoints in a C++ Program Compiled and Linked with -g2

(ladebug) stop in Thing::Thing
Select an overloaded function(1)
---------------------------------------------------- 
     1 Thing::Thing(char* const) 
     2 Thing::Thing(const int) 
     3 Thing::Thing(void) 
     4 None of the above 
---------------------------------------------------- 
3
[#1: stop in Thing::Thing(void) ] 
(ladebug) stop in Thing::Thing(const int)
[#2: stop in Thing::Thing(const int) ] 
 
(ladebug) stop in dump
Symbol dump not visible in current scope. 
dump has no valid breakpoint address 
Warning: Breakpoint not set 
(ladebug) stop in Thing::dump
[#3: stop in void Thing::dump(const char* const) ](2)
 

  1. Ladebug can display all the constructors. Note also the need for the Thing:: scope qualification; Thing:: is part of the name of the routine.
  2. Thing:: is part of the name for the function dump.

If your executable file contains limited symbolic debugging information, Ladebug lacks information to set breakpoints as shown in Example 14-2.

Example 14-2 Setting Breakpoints in a C++ Program Compiled with -g2 and Linked with -x

(ladebug) stop in Thing::Thing
Thing is not a valid breakpoint address 
Warning: Breakpoint not set(1)
(ladebug) stop in Thing(2)
Thing is not a valid breakpoint address 
Warning: Breakpoint not set 
(ladebug) stop in Thing::~Thing 
stop in Thing::~Thing 
Unable to parse input as legal command or C++ expression. 
(ladebug) stop in ~Thing 
stop in ~Thing 
Unable to parse input as legal command or C++ expression. 
(ladebug) stop in dump 
[#1: stop in dump ](3)
 

  1. Even after resetting the language, Ladebug still cannot set the breakpoint.
  2. Repeated attempts to set breakpoints in constructors fail.
  3. Ladebug can still set a breakpoint on this function because dump is unique and not dependent upon the classname Thing:: to distinguish it.

14.2.1.2 Listing the Source Code

Example 14-3 shows how Ladebug can list the source code corresponding to the position of the program counter if your executable file contains full debugging information.

Example 14-3 Listing the Source Code of a C++ Program Compiled and Linked with -g2

(ladebug) run
[1] stopped at [Thing::Thing(void):58 0x120002170] 
(Cannot find source file classdefinition.C) 
(ladebug) use ./src
Directory search path for source files: 
 . ./bin /usr/users/debug/ladebug ./src 
(ladebug) list
     59     dump ("Thing constructor, no arguments"); 
     60 } 
     61 
     62 
     63 Thing::Thing (const Thing1 t1) 
     64     : thisThing1 (t1), 
     65       thisThing2 (bogusThing2), 
     66       thisSideEffect (1) 
     67 { 
     68     sideEffect++; 
     69     dump ("Thing constructor, Thing1 argument"); 
     70 } 
     71 
     72 #ifndef CHANGE_ORDER 
     73 Thing::Thing (const Thing2 t2) 
     74     : thisThing1 (bogusThing1), 
     75       thisThing2 (t2), 
     76       thisSideEffect (1) 
     77 { 
     78     sideEffect++; 
     79     dump ("Thing constructor, Thing2 argument"); 
   

Without full symbolic debugging information, Ladebug does not know name of the source file. It can display some information for the routine dump because it is unique and not dependent upon the Thing:: class.

14.2.1.3 Displaying the Stack Trace

If your executable file contains full debugging information, Ladebug can display the stack trace of currently active functions. In Example 14-4, note the detailed call stack with class types and values in them.

Example 14-4 Displaying the Stack Trace of a C++ Program Compiled and Linked with -g2

(ladebug) where
>0  0x120002170 in ((Thing*)0x11ffff7c8)->Thing() classdefinition.C:58 
#1  0x120002574 in main() classdefinition.C:106 
 
(ladebug) cont
[3] stopped at [void Thing::dump(const char* const):93 0x1200023f0] 
     93     sideEffect++; 
 
(ladebug) where
>0  0x1200023f0 in ((Thing*)0x11ffff7c8)->dump(header=0x120001b80="Thing 
constructor, no arguments") classdefinition.C:93 
#1  0x120002198 in ((Thing*)0x11ffff7c8)->Thing() classdefinition.C:59 
#2  0x120002574 in main() classdefinition.C:106 
(ladebug) quit
 

If your executable file contains limited symbolic debugging information, Ladebug can show that you are in a routine called Thing but can't differentiate which one. Example 14-5 illustrates this.

Example 14-5 Displaying the Stack Trace of a C++ Program Compiled with -g2 and Linked with -x

(ladebug) where
>0  0x1200023e8 in dump(0x3ff80894608, 0x12000294f, 0x11ffff7c8, 0xc70, 
 0x3ff808941cc, 0x120002950) DebugInformationStrippedFromFile0:??? 
#1  0x120002198 in Thing(0x11ffff7c8, 0xc70, 0x3ff808941cc, 0x120002950, 
 0xd10, 0x3ffc0819100) DebugInformationStrippedFromFile0:??? 
#2  0x120002574 in main(0x3ffc0002078, 0xffffffff, 0x120001b70, 0x1, 
 0x140000060, 0x0) DebugInformationStrippedFromFile0:??? 
(ladebug) quit
 

14.2.2 Example C Program Linked with -x

This section presents a sample debugging session on a C program, first containing full symbolic debugging information, then compiled in the same way but linked with the -x flag. The operating system is DIGITAL UNIX 3.2.

In the second form of the program, -x strips all symbolic debugging information except for procedure and file information.

14.2.2.1 Setting Breakpoints on Routines

Example 14-6 invokes the user program with full debugging information and sets breakpoints on three routines: main, buildLocalList, and createNewElement.

Example 14-6 Setting Breakpoints on Routines in a C Program Compiled and Linked with -g2

 
csh> $LADEBUG ../bin/c_gflags001-g
Welcome to the Ladebug Debugger Version 4.0-9 
------------------ 
object file name: ../bin/c_gflags001-g 
Reading symbolic information ...done 
(ladebug) stop in main
[#1: stop in main ] 
(ladebug) stop in buildLocalList
[#2: stop in buildLocalList ] 
(ladebug) stop in createNewElement
[#3: stop in createNewElement ] 
(ladebug) run
[1] stopped at [void main(void):157 0x1200014b8](1)
    157  mainList = buildLocalList (5); 
(ladebug) 
 
 

  1. With full debugging information, when you stop at a breakpoint, Ladebug can determine the routine name, the line number, and the address for the routine.

Example 14-7 shows a program compiled with -g2 and linked with -x. In this case, the user program has all symbolic debugging information stripped, except for procedure and file information. The local (nonglobal) symbols are not preserved in the debugging information and Ladebug has no information to work with.

Example 14-7 Setting Breakpoints on Routines in a C Program Compiled with -g2 and Linked with -x

 
csh> $LADEBUG ../bin/c_gflags001-x
Welcome to the Ladebug Debugger Version 4.0-9 
------------------ 
object file name: ../bin/c_gflags001-x 
Reading symbolic information ...done 
(ladebug) stop in main
[#1: stop in main ] 
(ladebug) stop in buildLocalList
[#2: stop in buildLocalList ] 
(ladebug) stop in createNewElement
[#3: stop in createNewElement ] 
(ladebug) run
[1] stopped at [main:??? 0x1200014b0](1)
 

  1. In this example, there is no line number information and the start address is slightly different (0x1200014b0).

Ladebug normally starts on the first line of the source code. It skips over initialization and other bookkeeping information in the prologue when you enter a routine, so that the stack and parameters are in the expected state. In this example, the information about the prologue is not available, so Ladebug does its best to stop in the routine.

14.2.2.2 Listing the Source Code

Example 14-8 shows how Ladebug can list the source code corresponding to the position of the program counter if your executable contains full debugging information,

Ladebug knows about the current program counter and displays lines from line 157.

Example 14-8 Listing the Source Code of a C Program Compiled and Linked with -g2

(ladebug) use ../src
Directory search path for source files: 
 . ../bin ../src 
 
 (ladebug) list
    158  dumpLocalList ("Local list"); 
    159 
    160  buildDuplicateList (); 
    161  dumpDuplicateList ("Duplicate list"); 
    162 
    163  return; 
    164 }  /* main */ 
    165 
  

In Example 14-9, the name of the source file has been stripped out completely from the symbol table. Ladebug makes up a name for this file: DebugInformationStrippedFromFile0.

Example 14-9 Listing the Source Code of a C Program Compiled with -g2 and Linked with -x

 
(ladebug) use ../src
Directory search path for source files: 
 . ../bin ../src 
 
 (ladebug) list
 (Can't find file DebugInformationStrippedFromFile0) 
 

The name Ladebug creates is of some value. In some cases, this may be the only way of discriminating between two different instances of an overloaded function name. For example, there may be two different functions named buildList that can only be resolved by using one of these generated source file names.

The file name "DebugInformationStrippedFromFile0" has the symbol table file number in it. For more complex programs, you could use odump(1) and stdump(1) to identify where you are in your code.

14.2.2.3 Displaying the Stack Trace

If your executable file contains full debugging information, Ladebug can display the stack trace of currently active functions with detailed information as shown in Example 14-10.

Example 14-10 Displaying the Stack Trace of a C Program Compiled and Linked with -g2

(ladebug) cont
[2] stopped at [buildLocalList:65 0x1200013ac] 
     65  firstElement = NULL_LIST;(1) 
(ladebug) where(2)
>0  0x1200013ac in buildLocalList(lengthOfList=5) gflags001a.c:65 
#1  0x1200014c4 in main() gflags001a.c:157 
(ladebug) c
[3] stopped at [createNewElement:44 0x120001348] 
     44  newElement = (ListElementHandle) malloc (sizeof (ListElement)); 
(ladebug) where(3)    
>0  0x120001348 in createNewElement(dataValue=0, useValue=0)gflags001a.c:44 
#1  0x1200013d8 in buildLocalList(lengthOfList=5) gflags001a.c:71 
#2  0x1200014c4 in main() gflags001a.c:157 
(ladebug) quit
 


Previous Next Contents Index