From: gordon@madmax.uwaterloo.ca (Gordon R. Strachan)
Subject: Re: xdb accessing 'opaque' data structures
Organization: University of Waterloo
Date: Thu, 19 Nov 1992 16:35:03 GMT

In article <BxxA12.LBA@fc.sde.hp.com> bruno@fc.hp.com (Bruno Melli) writes:
>> So the debugger know what _MyWidgetRec structure looks like, it just
>> can't figure out that typedef MyWidget.  It all very strange to me.
>
>This is how it is supposed to work:
>
>You have something like this in one file:
>
>struct foo *p;
>
>The compiler puts out debug info to the effect that p is a pointer
>to a struct foo. We don't know what foo is yet, so the compiler emits
>debug info for a "dummy" structure called foo.
>
>In another file, you define foo:
>
>struct foo { whatever..... };
>
>At link time, /usr/bin/pxdb is supposed to redirect the pointer
>in the debug info for p from the dummy structure foo to the real
>structure foo.
>
>Now the problem: 
>
>There used to be a bug in the debug info generated by the
>C compiler. Instead of calling the dummy structure "foo", the compiler
>would call it <<NULL SYMBOL>> (or something like that).
>With this, pxdb had no way of fixing the debug info for p as the matching
>was done on a string compare basis.
>
>My guess is that your program knows what the _MyWidgetRec in some
>modules, but that in the module where you use p, the type is still 
>opaque...
>A potential workaround if that's the case is to include a definition for
>_MyWidgetRec in the module where p is declared...

Well, its a little more bizarre than that.  To illistrate consider the
following example.  Suppose we create the file debugP.h which contains:


struct _MyStruct
{
 int v1;
 int v2;
} MyStruct;

Next a file called debug.h:

typedef struct _MyStruct *MyStructPtr;

finally, two files which call these.  First debug.c

#include <stdio.h>
#include "debug.h"

extern MyStructPtr getit();

main()


{
 MyStructPtr valptr;

 valptr = getit();
 doit(valptr);
}

and the file debug1.c

#include <stdio.h>
#include "debugP.h"
#include "debug.h"

MyStructPtr getit()

{
 MyStructPtr temp = (MyStructPtr) malloc(sizeof(MyStruct));
 return(temp);
}

doit(valptr)

MyStructPtr valptr;


{
 valptr->v2=1;
}

now, compile with cc -g -o debug debug.c debug1.c.  Go into the debugger and
put a break point in the getit() function.  Start the program and try to
print out the contexts of temp.  On a 700 (HPUX 8.07) it will return a
null symbol.  But, the structure was defined within the module, it should
now.  Now, add the line #include "debugP.h" to debug.c and recompile.  Put
the same breakpoint and now you will be able to print out the context of
temp.  Now, temp is completely defined in debug1.c and should be isolated
from what goes on in the file debug.c.  I am not even trying to debug a
routine in debug.c

As a last test (just to add some spice) go back to the original debug.c code
and compile with:

cc -g -o debug debug1.c debug.c

ie. change the order of the compiling.

You will now be able to print out the values of temp.  In fact, we can even
print out the fields of valptr in the mainline despite the fact the structure
is hidden from it.  So, the lesson we have learned is that you don't have
to define the structure in the module you are debugging but that the
structure can't be hidden from the first structure you link.

Given this, I would say the easier work around is to write a dummy file
which includes all the private widget header files and defines one instance
of each.  When debugging, you simply link this in first and everything should
work as planned.  I think that is easier than putting

#ifdef DEBUG
#include <CoreP.h>
#endif

everywhere.

I don't know though, I still think its a bug...

Gordon
>
>bruno.
>
>


Newsgroups: comp.sys.hp