A debugging problem (long)

Gordon Cross crossgl at ingr.com
Fri Feb 24 01:10:02 AEST 1989


In article <382 at marque.mu.edu> makani at marque.UUCP (Gautam Makani) writes:
>
>I have a piece of code to read in line entries from an object file
>and filter out some information. I get an EMT (core dump) and cannot
>figure out why.
>
>The problem happens when I access a particular part of a struct, *but*
> i) I can print out the constituent data in that area. 
> ii) Using "sdb" (UNIX debugger), I can access (look at) the variable.
> iii) Further, what puzzles me is that this happens the *second* time through
>      a loop.I know that seems stupid ...
>
> I would appreciate it if someone tells me what's going on. 

This is a common problem on many architectures.  In almost all likelyhood
you are suffering from an alignment problem (notice this line from your code):

>       lineptr = (char *)((long) lineptr + LINESZ);

It would appear that you have read the entire quantity of line number entries
into a buffer.  Then you are incrementing a pointer in the (apparantly) logical
way to access each line entry in turn.  Note that the macro LINESZ is defined
to be 6 (check /usr/include/linenum.h)!!  But if you try this:

printf ("Size of line entry is %d.\n", sizeof (struct lineno));

I will bet that (I am not familiar with the 3b15 in particular) the answer will
be 8!!  Have you figured it out yet?? If so hit 'n'...

The object file is written out without regard to the alignment requirements of
the struct lineno.  They pack them as tightly as possible to save on file size.
The reason why you are failing on the SECOND loop pass is that the field
'l_symndx' will be correctly aligned for every other struct lineno.  For
example (assumming 4-byte alignment on longs) if your buffer begins at 0x10000
you have:

         lineno #1 ([0]) at address 0x10000 (correctly aligned)
         lineno #2 ([1]) at address 0x10006 (incorrectly aligned)
         lineno #3 ([2]) at address 0x1000c (correctly aligned)
                               .
                               .
                               .

You are going to have to do one of several things to correct this problem:

1) copy every other struct lineno into a static location (with proper alignment
   of course - simply declare a struct lineno variable and you've got it) as
   you peruse your buffer.

2) read the struct lineno's from the file one at a time into an array using
   ptr++ instead of ptr = (struct lineno *)((char *)ptr + LINESZ).  You can
   do this yourself or use the 'ld' routines described in section 3X of the
   AT&T manuals.

I like solution (1) because it will usually run faster than solution (2) but
solution (2) has the advantage of simplicity...

As regards sdb??  It seemingly works because of the nature of ptrace (which
sdb uses to copy data from your process for examination).  If the symbol
table says something is a long, sdb gets the data realigned as a side effect
of copying it!!

>I realize this is utilizing precious bandwidth. Please reply by e-mail
>and thanks in advance.

Ooops!  Well I guess this is of interest to everyone...
-- 

Gordon Cross             UUCP:      uunet!ingr!crossgl     "all opinions are
111 Westminister Way     INTERNET:  crossgl at ingr.com        mine and not those
Madison, AL 35758        MA BELL:   (205) 772-7842          of my employer."



More information about the Comp.unix.questions mailing list