Brief Installation Notes (from Frank Mueller)


Annotated Installation Instructions

  1. To get a thread debugging environment, you have to install the TDI (shared libraries and header files) and patch the debugger and pthread implementations.
  2. The first step is to install the TDI library. The TDI library is the generic part used by the debugger (via IPC) and the TED implementation. It should be installed to a common location accessible by the dynamic linker, because it is loaded at runtime by the TED part of the pthreads implementation. There are header files installed, that are necessary to compile a TDI aware debugger and the patched pthreads implementations. With the configure option --prefix you can choose the directory, where all libraries are installed to <prefix>/lib and header files are copied to <prefix>/include
  3. The second step is to patch a debugger (Gdb) and your favourite pthreads implementation ( FSU, MIT and an experimental Linuxthreads patch)

GDB as a Thread Debugger on top of the TDI


The following modifications to the GDB were made to demonstrate the TDI efficiency. The GDB as a TDI client uses the abstract POSIX thread level view to debug threads. All thread information will be generated by the TDI and is send back to the Debugger via IPC. The TDI interface for the Gdb is the client library of the TDI - libTDIClt.so or libTDIClt.a. The client library contains all IPC stuff reqired to communicate with the TDI kernel running on the application side. The client library is part of the TDI distribution.

Major changes to the GDB (version 4.17) were made by adding a new file pthread.c, that contains the implementation af all thread debugging commands based on the TDI. The following new commands available are listed on the TDI home page.

Low Level Changes to the GDB

Minor changes were made by modiffying the files infcmd.c, infrun.c and breakpoint.c and some target specific header files:
 
 

file
 
description of changes 
infcmd.c in gdb-4.17/gdb

step_1
The commands step, stepi, next and nexti  are based on the function step_1. To provide the appropriate threadspecific commands  named ptstep, ptstepi, ptnext and ptnexti we have to change the stop criterion used in step_1. If we stop in the next line or at the next instruction, we have to test the current thread. If it is not the same as before running the command (this means, that we have lost the control flow of the thread), we have to continue running the program until the former control flow is reached. 
infrun.c in gdb-4.17/gdb

wait_for_inferior: 
 
bugfix for recursive calls of wait_for_inferior:
wait_for_inferior is the function called by proceed() to wait for any program event signalled by the operating system by making the function wait return. wait_for_inferior calls the function breakpoint_thread_match before deciding to proceed again, if it was the wrong thread. Calling the function breakpoint_thread_match can cause a TDI usage. If we debug an application using a User Space Implementation of the Pthreads, a function call is done  in the target. The consequence of a target function call in this situation is a recursive call of wait_for_inferior. After target function call is completed, the flag breakpoint_inserted is unset. This is a wrong assignment, because the breakpoint we were calling breakpoint_thread_match at is not unset. The bugfix is very simple by setting the flag  breakpoint_inserted.
switch off scheduling while resetting the breakpoint:
If the current breakpoint was reached from the wrong thread, we have to pass this breakpoint by resetting the instruction, single stepping and resetting the breakpoint after this single step. While single stepping the application, no breakpoint is set. This a critical point, because other threads can be scheduled in and pass the breakpoint without stop. To avoid this scenario, we switch off signal handling in user space implementations by changing the signal handing policy of the pthreads implementation. switching off is done by setting a flag in the target process. this flag is a symbol, that is defined in every TDI compliant pthread implementation.
breakpoint.c in gdb-4.17/gdb
!!! there is a distinction made between kernel threads (named thread) and POSIX threads (named pthread) !!!

breakpoint_thread_match: 

breakpoint_thread_match is the function used by wait_for_inferior to test the validity of a threadspecific breakpoint. Because there is the abilty for the user to specify threadspecific breakpoints for POSIX threads now, some changes were made to test the validity of a POSIX threadspecific breakpoint.
break_command_1:
the keyword pthread is accepted by the break command. some parsing and assignment stuff is added. 
native support files in gdb-4.17/gdb/config/xxx/ :

i.e. nm-i386sol2.h; nm-linux.h; nm-hppah.h; nm-sun4sol2.h


definition of target_new_objfile:
target_new_objfile is defined as a function call to pTDI_new_objfile to initialize the thread debugging. The GDB does a target_new_objfile on every object file load. The application has to know, whether it is thread debugged or not. If it is, it loads the TDI library and register it's TED functions (functions to access object attributes and iterate object sets). Because we have to set the thread debug mode of the application before running it, it's the best way to detect a pthread application while scanning the loaded object files for pthread symbols. Setting the debug mode is done by writing the global symbol pthread_debug_with_TDI, that has to be defined in a TDI compliant pthreads implementation. 

Gdb Patch

All changes to GDB are bundled in a  patch (see TDI home page) applicable to the source tree of gdb. Download the patch and execute a

% patch -p0 < gdb-*-TDI.patch

in the directory containig the gdb source tree named gdb-version. After patching you have to configure and install the gdb according to the following installation guide.

!!! General information: Please try to compile the gdb first without changing to fix all problems not referring to this patch. Some newer Linux distributions come up with a restructured include file hierarchy. These problems are not covered by this patch and should be fixed by you first. !!!

Installation

After patching the Gdb sources you have to reconfigure the gdb for TDI. The configure script and it's sources (configure.in, acconfig.h) were modified to configure for TDI now. To get TDI support execute the command:

% configure --enable-TDI

To compile and link the gdb (with: make && make install) successfully you have to install the TDI first (see the TDI INSTALL file). The library libTDIClt.so  should be reachable by the linker and the header files tdi.h and tdi-client.h have to be installed properly.
 
 


last modified: 1999-Jul-26
authors: Daniel Schulz , Frank Mueller