delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/06/10/02:45:31

From: George Foot <mert0407 AT sable DOT ox DOT ac DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Forcing Traceback output with debuging purposes of a library.
Date: 10 Jun 1998 05:54:09 GMT
Organization: Oxford University, England
Lines: 65
Message-ID: <6ll721$59n$2@news.ox.ac.uk>
References: <m0yjWGE-0001KcC AT vivaldi DOT ort DOT edu DOT uy>
NNTP-Posting-Host: sable.ox.ac.uk
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

On Tue, 9 Jun 98 18:48 GRNLNDST in comp.os.msdos.djgpp
lubaldo AT adinet DOT com DOT uy wrote:

:     I am adding some debuging capabilities to my PPCol library but I don't
: know how to force the output of the traceback, so the user can trace all the
: calls to functions and look where happened the problem.

I think the problem is that the signal is raised by your call
directly, and so __djgpp_exception_state_ptr is not set properly; this
means that the register status, etc, is not available to the traceback
printer in the normal way.  I found this out a while ago.  I only had
the sources for version 2.02 on my hard drive, which seem to have this
fixed (or fudged...); although the default handler doesn't get the
information, my replacement handler (which generates core dumps
containing the information) does work, because it uses the same system
that the v2.02 library uses.

You could do the fix in your code before raising the signal, I
think... but that would be ugly.  IIRC:

    jmp_buf fake_exception_state;
    if (setjmp (fake_exception_state)) {    /* shouldn't happen */
        fprintf (stderr, "Argh!\n");
        exit (-1);
    }
    __djgpp_exception_state_ptr = &fake_exception_state;
    raise(SIG...);

I can't test this now, because I can't run djgpp on this computer.  I
don't think this is a nice way to solve the problem though.

The most robust way is probably to generate the traceback yourself.
It's not too hard; you get the value of EBP.  At that location in your
stack segment (same as data segment) is the next value for EBP
(32-bit), and at EBP+4 is the EIP to print.  Keep going until *(int
*)EBP is zero; don't print ((int *)EBP)[1] here.

The best way to see this is to get the library source, and look in
src/libc/go32/dpmiexcp.c at the function `show_call_frame'.  It's
slightly complicated because it reads its values from
__djgpp_exception_state (which you can't do).  You can use some short
inline assembly to get the register contents you need (just EBP and
perhaps EIP, really).

If you want symify to work on your output you just need to print the
numbers in hex, as a series of lines all starting with "  0x".  That's
enough for symify to work, but again it's kludgy.  You could link in
-ldbg and call the symbol name lookup routines yourself.

In fact everything I've suggested here doesn't feel `nice' to me; I'm
sorry if it's not very useful!

:     Some bad DPMI servers don't detect some bad memory accesses... I don't
: know what happens when you access the NULL space with this DPMI servers...
: maybe in that situation they detect it, but someone know if this is 100%
: effective? I don't have tried it under W95 yet... sorry... I don't have much
: time...

Relying on the NULL page is probably not a good idea, for the reason
you gave -- Win95 for instance doesn't detect the accesses.

-- 
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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019