Mail Archives: djgpp/1998/10/24/15:40:16
On Sat, 24 Oct 1998, John Kissell wrote:
> The following is a snippet from a 'C' file that contains many long and
> nested structures. By nested, a main structure 'OBJECT_TYPE *list'
> contains pointers to other structures which contain pointers to lesser
> structures and so on. It compiles and links with no errors *or warnings*
> but I get a SIGSEGV at the 'p=record->text;' line. The rub is that Rhide
> in 'run to cursor' and then debug shows that record->text contains a
> valid string of type char, and in fact, the correct string in the
> correct place for the file that was read in as a test of the code! But
> the program when run unhindered under Rhide stops with a SIGSEGV at the
> 'p = record->text;' line?
When programs are run under a debugger their environment is
different, so they can behave differently (if the code is
wrong, of course -- correct code should work the same way in
both cases).
Try dumping to a disk file, or stderr, the value of `record'
before the above assignment. They you may be able to spot
whether or not it's a valid pointer (but you'll need to take a
look at more of the crash dump to do this).
Also note that in optimised programs it's sometimes not possible
to determine exactly which line was being executed at the time
of the error. That's not advocating that you shouldn't use
optimisation; just that you should be aware of this fact when
you debug your code.
> ps. I typed part of the error codes generated when the program was run
> directly from the DOS prompt (from a 'print screen' printout). I would
> like to capture them all to include here but I dont know how. :(
Use `redir':
redir -e crash.txt myprog.exe
That will capture everything sent to stderr (including the crash
dump) and redirect it to the file `crash.txt'. I believe
`symify' can also do this, after the event, if you type:
symify -o crash.txt myprog.exe
I also suggest you put in some assertions. Before dereferencing
any pointer, assert that it is not NULL. #include <assert.h>,
and then:
> int ParseFile(OBJECT_TYPE *list)
> { char command[6][2] = {"Z","X","K","I","T","G"},
> *p,*p1,*p2,tmp[256],tmp2[256];
> int n,G;
> double CX=0,CY=0,CI=0,CJ=0,X=0,Y=0,I=0,J=0,arc,start,inc,r;
> RECORD_TYPE *record;
> OBJECT_TYPE *graph_win;
>
assert (list);
> graph_win=TagSearch(list,GRAPH_WIN); /* in debug this points to the
> correct data */
assert (graph_win);
assert (graph_win->file);
> record=graph_win->file->records; /* this also */
> vflag.max=vflag.graph=0; /* and this */
> view_count=0; /* I'll get rid of this global
> eventually */
>
> do{
> X=CX; Y=CY;
> vflag.park = 0; /* this one too */
assert (record);
> p = record->text; /******* SIGSEGV first flagged here ******/
> p1 = tmp; /* Run to cursor at the *end* of this line and then
> debug in Rhide shows that record->text contains exactly what it is
> supposed to?
If you "#define NDEBUG" before including the `assert.h' header
file then all the assertions will compile down to nothing (in an
optimised compile), so you don't need to sacrifice any
efficiency in your releases.
> ps3: The OBJECT_TYPE structure does contain pointers to ALLEGRO entities
> but none are referenced herein. So am I correct in assuming that the
> 'Shutting down Allegro' message is just a hook into DJ's shutdown
> procedure to unload ALLEGRO interrupts?
Yes; Allegro hooks various signals so that it can get itself out
of the way while your program continues to crash. Errors like
this one may be caused by Allegro, or may occur in Allegro
routines, or may be nothing to do with Allegro at all; in any
case, it shuts itself down, printing its message.
--
george DOT foot AT merton DOT oxford DOT ac DOT uk
xu do tavla fo la lojban -- http://xiron.pc.helsinki.fi/lojban/lojban.html
- Raw text -