[ Previous | Next | Table of Contents | Index | Library Home | Legal | Search ]

General Programming Concepts: Writing and Debugging Programs


Developing Multi-Threaded Program which examines and modifies pthread library objects

The pthread debug library (libpthdebug.a) provides a set of functions which allow application developers with the capability to examine and modify pthread library objects.

This library can be used for both 32-bit applications and 64-bit applications. This library is thread safe. The pthread debug library contains a 32-bit shared object and a 64-bit shared object.

The pthread debug library provides applicaitons access to the pthread library information. This includes information on pthreads, pthread attributes, mutexes, mutex attributes, condition variables, condition variable attributes, read/write locks, read/write lock attributes, and information about the state of the pthread library.

Note: All data (addresses, registers) returned by this library will be in 64-bit format both for 64-bit and 32-bit application. It is the applications responsibility to convert these values into 32-bit format for 32-bit applications. When debugging a 32-bit application the top half of addresses and registers will be ignored.

Note: The pthread debug library does not report mutexes, mutexattrs, conds, condattrs, rwlocks, rwlockattrs that have the pshared value of PTHREAD_PROCESS_SHARED.

Initialization

The application must initialize a pthread debug library session for each pthreaded process. The pthdb_sessison_init() function must be called from each pthreaded process after the process has been loaded. The pthread debug library supports one session for a single process. The application must assign a unique user identifier and pass it to the pthdb_session_init() function which in turn will assign a unique session identifier which must be passed as the first parameter to all other pthread debug library functions, except pthdb_session_pthreaded(), in return. Whenever the pthread debug library invokes a call back function, it will pass the unique application assigned user identifier back to the application. The pthdb_session_init() function checks the list of call back functions (Multi-Threaded Call Back Functions) provided by the application, and initializes the session's data structures. Also, this function sets the session flags. An appplication must pass the PTHDB_FLAG_SUSPEND flag to the pthdb_session_init, see the pthdb_session_setflags() function for a full list of flags.

Call Back Functions

The pthread debug library uses the call back functions to to obtain data, to write data, and to give storage management to the application. See Call Back Functions (Multi-Threaded Call Back Functions) for more information.

Required call back functions for an application:

Optional call back functions for an application:

Update Function

Each time the application is stopped, after the session has been initialized, it is necessary to call the pthdb_session_update() function. This function sets or reset the lists of pthreads, pthread attributes, mutexes, mutex attributes, condition variables, condition variable attributes, read/write locks, read/write lock attributes, pthread specific keys and active keys. It uses call back functions to manage memory for the lists.

Context Functions

The pthdb_pthread_context() function is used to get the context information and the pthdb_pthread_setcontext() function is used to set the context. The pthdb_pthread_context() function obtains the context information of a pthread from either the kernel or the pthread data structure in the application's address space. If the pthread is not associated with a kernel thread, then the context information saved by pthread library is obtained. If a pthread is associated with a kernel thread, the information is obtained from the application using the call back functions, it is the applications responsibility to determine if the kernel thread is in kernel mode or user mode and provide the correct information for that mode.

When a pthread with kernel thread is in kernel mode code it is impossible to get the full user mode context because the kernel does not save it off in one place. The getthrds() function can be used to get part of this information. It always saves the user mode stack and the application can discover this by checking thrdsinfo64.ti_scount. If this is non-zero the user mode stack is available in thrdsinfo64.ti_ustk. From user mode stack it is possible to determine the iar and the call back frames but not the other register values. The thrdsinfo64 structure is defined in procinfo.h file.

List Functions

The pthread debug library maintains lists for pthreads, pthread attributes, mutexes, mutex attributes, condition variables, condition variables attributes, read/write locks, read/write lock attributes, pthread specific keys and active keys, each represented by a type specific handle. The pthdb_<object>() functions return the next handle in the appropriate list, where object is one of the following: pthread, attr, mutex, mutexattr, cond, condattr, rwlock, rwlockattr or key. If the list is empty or the end of the list is reached, PTHDB_INVALID_<OBJECT> is reported, where OBJECT is one of the following: PTHREAD, ATTR, MUTEX, MUTEXATTR, COND, CONDATTR, RWLOCK, RWLOCKATTR or KEY.

Field Functions

Detailed information about an object can be obtained by using the appropriate object member function, pthdb_<object>_<field>(), where object is one of the following: pthread, attr, mutex, mutexattr, cond, condattr, rwlock, rwlockattr or key and where field is the name of a field of the detailed information for the object.

Customizing the Session

The pthdb_session_setflags() function allows the application to change the flags which customize the session. These flags are used to control the number of registers that are read or wrote during context operations.

The pthdb_session_flags() function gets the current flags for the session.

Session Termination

At the end of the session, the session data structures need to be deallocated and the session data needs to be deleted. This is accomplished by calling the pthdb_session_destroy() function, which uses a call back function to deallocate the memory. All of the memory allocated by the pthdb_session_init(), and pthdb_session_update() functions will be deallocated.

Example

Pseudo-code showing how an application can connect to the pthread debug library:

/* includes */
 
#include <pthread.h>
#include <sys/pthdebug.h>
 
...
 
int my_read_data(pthdb_user_t user, pthdb_symbol_t symbols[],int count)
{
  int rc;
 
  rc=memcpy(buf,(void *)addr,len);                              
  if (rc==NULL) {                                               
    fprintf(stderr,"Error message\n");
    return(1);                                                  
  }                                                             
  return(0);                                                    
}
int my_alloc(pthdb_user_t user, size_t len, void **bufp)
{
  *bufp=malloc(len);                                            
  if(!*bufp) {                                                  
    fprintf(stderr,"Error message\n");
    return(1);                                                  
  }                                                             
  return(0);                                                    
}
int my_realloc(pthdb_user_t user, void *buf, size_t len, void **bufp)
{
  *bufp=realloc(buf,len);                                    
  if(!*bufp) {                                               
    fprintf(stderr,"Error message\n");
    return(1);                                               
  }                                                          
  return(0);                                                 
}
int my_dealloc(pthdb_user_t user,void *buf)
{
  free(buf); 
  return(0); 
}
 
status()
{
  pthdb_callbacks_t callbacks =
                    {  NULL,                
                       my_read_data,  
                       NULL, 
                       NULL,                
                       NULL,                
                       my_alloc,            
                       my_realloc,          
                       my_dealloc,          
                       NULL                 
                    };
 
  ...
 
  rc=pthread_suspend_others_np();
  if (rc!=0)
    deal with error
 
  if (not initialized)
    rc=pthdb_session_init(user,exec_mode,PTHDB_SUSPEND|PTHDB_REGS,callbacks,
                          &session);
    if (rc!=PTHDB_SUCCESS)
       deal with error
 
  rc=pthdb_session_update(session);
  if (rc!=PTHDB_SUCCESS)
        deal with error
  
   retrieve pthread object information using the object list functions and 
   the object field functions
 
  ...
  
  rc=pthread_continue_others_np();
  if (rc!=0)
    deal with error
}
 
...
 
main()
{
  ...
}

Related Information

The pthread.h file

Developing Multi-Threaded Programs


[ Previous | Next | Table of Contents | Index | Library Home | Legal | Search ]