From: George Foot 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: NNTP-Posting-Host: sable.ox.ac.uk To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk 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