Symbols for dbx when you have not compiled -g

Sometimes symbolic debuggers are just easier and quicker to use than non ymbolic debuggers. So when a user application dumps core or as in this case was behaving strangely according to the customers a gcore was provided it would be nice to not have to work out the offsets of each structure by hand and then use dbx's examine command to dump them out.

Specifically I wanted to take a peek at the ulwp_t structure that each thread. More specifically I wanted to look at the list of zombie threads. However the specifics are not really the point of this post, since most of what I wanted is printed by the “thread -info” dbx command.

Since the application is not compiled with the -g flag and nor are the libraries this could mean a load of hurt with examine. However if you have the source, and for OpenSolaris we all do there is another way. (My example is from SunOS 5.8 but apart from the definition being in a different header file the example will work on any release.)

The trick is to build a shared library that contains the definitions that you are interested in and then use the “loadobject -load” command to load it. If you then set the scope to be that file you can print the objects symbolically.

: s4u-60b-gmp03.eu TS 145 $; cat tat.c
#include <libthr.h>

ulwp_t \*foo = 0;

: s4u-60b-gmp03.eu TS 146 $; cc -g -I /share/bld/ONclones/on28-patch-eu/usr/src/uts/sparc -I /share/bld/ONclones/on28-patch-eu/usr/src/lib/liblwp/common -o tat.so -G tat.c
: s4u-60b-gmp03.eu TS 147 $; dbx binary core
Reading binary
core file header read successfully
Reading ld.so.1
Reading libpthread.so.1
.
.
t@151 (l@151) terminated by signal 0 (UNKNOWN SIGNAL)
0xfeee4d7c: __lwp_park+0x0010:  ta       8
(dbx) loadobject -load tat.so
Reading tat.so
Loaded loadobject: /share/eu/bld/scratch/cg13442/tmp/core/tat.so
(dbx) file tat.c            
(dbx) print \*((ulwp_t \*)all_zombies)
\*((ulwp_t \*) all_zombies) = {
    ul_self             = 0xfed23600
    ul_tls              = {
        tls_data = (nil)
        tls_size = 0
    }
    ul_forw             = 0xfe430000
    ul_back             = 0xfbfbc400
    ul_next             = (nil)
    ul_hash             = (nil)
    ul_rval             = (nil)
    ul_stk              = 0xfb000000 "<bad address 0xfb000000>"
    ul_mapsiz           = 0
    ul_guardsize        = 0
.
.
.
.
    ul_td_events_enable = '\\0'
    ul_sync_obj_reg     = '\\0'
    ul_qtype            = '\\0'
    ul_handoff          = '\\0'
    ul_usropts          = 128
    ul_startpc          = 0xfbccd568 = &worker_thread()
    ul_startarg         = 0x16e6bb8
    ul_wchan            = (nil)
.
.
.
.
    ul_savedregs        = {
        rs_pc     = 0
        rs_sp     = 0
        rs_o7     = 0
        rs_g1     = 0
        rs_g2     = 0
        rs_g3     = 0
        rs_g4     = 0
        rs_fsr    = 0
        rs_fpu_en = 0
    }
}
(dbx) 
(dbx) print ((ulwp_t \*)all_zombies)->ul_startpc
((ulwp_t \*) all_zombies)->ul_startpc = 0xfbccd568 = &worker_thread()
(dbx) print ((ulwp_t \*)all_zombies)->ul_forw->ul_startpc
((ulwp_t \*) all_zombies)->ul_forw->ul_startpc = 0xfbccd568 = &worker_thread()
(dbx) print ((ulwp_t \*)all_zombies)->ul_forw->ul_forw->ul_startpc
((ulwp_t \*) all_zombies)->ul_forw->ul_forw->ul_startpc = 0xfbccd568 = &worker_thread()
(dbx) 

Clearly you can use this technique with any data structure. I always feel there should be a better way so look forward to having it explained to me in the comments to this post.


Tags:

Comments:

Post a Comment:
Comments are closed for this entry.
About

This is the old blog of Chris Gerhard. It has mostly moved to http://chrisgerhard.wordpress.com

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today