Can we get line which caused an unhandled exception

A

Angus

The exception that is being raised in one of my applications I can
only catch by the unhlandled exception handler. But many functions
could have caused this exception. Just knowing I have an unhandled
excpetion doesn't help with debugging. I would ideally like to get
the line and file causing the exception? Is this possible? How can I
get more information so I can sned to log?
 
R

red floyd

Angus said:
The exception that is being raised in one of my applications I can
only catch by the unhlandled exception handler. But many functions
could have caused this exception. Just knowing I have an unhandled
excpetion doesn't help with debugging. I would ideally like to get
the line and file causing the exception? Is this possible? How can I
get more information so I can sned to log?

Once you're in either unexpected(), all you can do is either re-throw,
or drop dead. If you're in terminate(), you're pretty much toast.
 
P

Pascal J. Bourguignon

Angus said:
The exception that is being raised in one of my applications I can
only catch by the unhlandled exception handler. But many functions
could have caused this exception. Just knowing I have an unhandled
excpetion doesn't help with debugging. I would ideally like to get
the line and file causing the exception? Is this possible? How can I
get more information so I can sned to log?

Well the most practical solution I see is to switch to Common Lisp
which has the ability to call the condition handlers in the dynamic
context of the condition.


AFAIK, in C++, you just lose.

What you could do, but of course it'll apply only to code of which you
may modify the sources, is to edit all the exception classes and all
the throw expressions to add __FILE__ and __LINE__ as parameter to the
exceptions.



Example: Two functions throwing an ERROR "exception" 1/10 of the time:

C/USER[14]> (defun f (n) (when (zerop (random 10)) (error "SIMPLE ERROR ~D" n)))
F
C/USER[15]> (defun g (n) (when (zerop (random 10)) (error "SIMPLE ERROR ~D" n)))
G

We call them with a dynamic handler:

C/USER[16]> (handler-bind ((error (lambda (condition) (invoke-debugger condition))))
(loop :for n :from 0 :do (f n) (g n)))

*** - SIMPLE ERROR 6
The following restarts are available:
ABORT :R1 Abort main loop

Ok, so which was it, F or G?


C/Break 1 USER[17]> :bt
<1/257> #<SYSTEM-FUNCTION EXT:SHOW-STACK> 3
<2/250> #<COMPILED-FUNCTION SYSTEM::pRINT-BACKTRACE>
<3/244> #<COMPILED-FUNCTION SYSTEM::DEBUG-BACKTRACE>
<4/235> #<SYSTEM-FUNCTION SYSTEM::READ-EVAL-PRINT> 2
<5/232> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP-2-3>
<6/228> #<SYSTEM-FUNCTION SYSTEM::SAME-ENV-AS> 2
<7/214> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP-2>
<8/212> #<SYSTEM-FUNCTION SYSTEM::DRIVER>
<9/172> #<COMPILED-FUNCTION SYSTEM::BREAK-LOOP>
<10/169> #<SYSTEM-FUNCTION INVOKE-DEBUGGER>
[168] EVAL frame for form (INVOKE-DEBUGGER CONDITION)
[153] APPLY frame for call :)LAMBDA '#<SIMPLE-ERROR #x0003340A4D20>)
<11/149> #<FUNCTION :LAMBDA (CONDITION) (INVOKE-DEBUGGER CONDITION)> 1
<12/146> #<COMPILED-FUNCTION #:COMPILED-FORM-969>
<13/141> #<SYSTEM-FUNCTION SIGNAL> 1
<14/135> #<SYSTEM-FUNCTION ERROR> 2
[133] EVAL frame for form (ERROR "SIMPLE ERROR ~D" N)
<15/131> #<SPECIAL-OPERATOR WHEN>
[129] EVAL frame for form (WHEN (ZEROP (RANDOM 10)) (ERROR "SIMPLE ERROR ~D" N))
[114] APPLY frame for call (G '6)

Well this time it was G.


<16/110> #<FUNCTION G (N) (DECLARE (SYSTEM::IN-DEFUN G)) (BLOCK G (WHEN (ZEROP (RANDOM 10)) (ERROR "SIMPLE ERROR ~D" N)))> 1
[109] EVAL frame for form (G N)
<17/106> #<SPECIAL-OPERATOR PROGN>
[105] EVAL frame for form (PROGN (F N) (G N))
<18/93> #<SPECIAL-OPERATOR TAGBODY>
[92] EVAL frame for form (TAGBODY SYSTEM::BEGIN-LOOP (PROGN (F N) (G N)) (PSETQ N (+ N 1)) (GO SYSTEM::BEGIN-LOOP) SYSTEM::END-LOOP)
<19/85> #<SPECIAL-OPERATOR LET>
[83] EVAL frame for form (LET NIL (TAGBODY SYSTEM::BEGIN-LOOP (PROGN (F N) (G N)) (PSETQ N (+ N 1)) (GO SYSTEM::BEGIN-LOOP) SYSTEM::END-LOOP))
<20/74> #<SPECIAL-OPERATOR LET>
[72] EVAL frame for form (LET ((N 0)) (LET NIL (TAGBODY SYSTEM::BEGIN-LOOP (PROGN (F N) (G N)) (PSETQ N (+ N 1)) (GO SYSTEM::BEGIN-LOOP) SYSTEM::END-LOOP)))
[59] APPLY frame for call :)LAMBDA)
<21/56> #<FUNCTION :LAMBDA NIL (PROGN (LOOP :FOR N :FROM 0 :DO (F N) (G N)))> 0
<22/50> #<COMPILED-FUNCTION #:COMPILED-FORM-969>
<23/51> #<SPECIAL-OPERATOR LOCALLY>
[50] EVAL frame for form (LOCALLY (DECLARE (COMPILE)) (SYSTEM::%HANDLER-BIND #:G10021 'ERROR #'(LAMBDA (CONDITION) (FUNCALL (FUNCALL #:G10020) CONDITION))))
<24/39> #<SPECIAL-OPERATOR LET>
[37] EVAL frame for form
(LET
((#1=#:G10020 #'(LAMBDA NIL (PROGN (LAMBDA (CONDITION) (INVOKE-DEBUGGER CONDITION)))))
(#2=#:G10021 #'(LAMBDA NIL (PROGN (LOOP :FOR N :FROM 0 :DO (F N) (G N))))))
(LOCALLY (DECLARE (COMPILE)) (SYSTEM::%HANDLER-BIND #2# 'ERROR #'(LAMBDA (CONDITION) (FUNCALL (FUNCALL #1#) CONDITION)))))
Printed 24 frames
C/Break 1 USER[17]>


Notice that since the handler is in the dynamic context of the
exception, it can _correct_ the problem, and return or "break" to a
sane situation so the processing may go on.
 
V

Vladyslav Lazarenko

The exception that is being raised in one of my applications I can
only catch by the unhlandled exception handler.  But many functions
could have caused this exception.  Just knowing I have an unhandled
excpetion doesn't help with debugging.  I would ideally like to get
the line and file causing the exception?  Is this possible?  How can I
get more information so I can sned to log?

Just catch the case in debugger and print stack trace.
 
J

James Kanze

The exception that is being raised in one of my applications I
can only catch by the unhlandled exception handler. But many
functions could have caused this exception. Just knowing I
have an unhandled excpetion doesn't help with debugging. I
would ideally like to get the line and file causing the
exception? Is this possible? How can I get more information
so I can sned to log?

It depends on the implementation. If you have an unhandled
exception, and you've not installed any handlers yourself, the
program should core dump (or its moral equivalent under your
system). Depending on the implementation, the stack may or may
not have been unwound---from a quality of implementation point
of view, if technically feasable, I would expect it not to have
been unwound. In which case, a debugger should reveal where the
exception was thrown.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top