currently, there's no way to execute some function attached to a specific 'catch block' right before unwinding the stack, after a thrown exception/error.
The only thing we can do is set a custom Runtime.traceHandler, but this cannot depend on the catch block (and doing so for every catch block would hurt performance)
This prevents attaching a debugger right before stack unwinding at the root of the program in the following scenario:
----
void fun(){
try{...}catch{...}
// code that may throw and is usually caught in normal setting
// occasionally some unusual exceptions/errors won't be caught
}
void call_debugger(){
//raise signal so we can attach a debugger
}
void main(){
try{
fun();
}
catch(Throwable t){
// we want to call call_debugger after an uncaught exception lands here but before stack unwinds, because most information is lost after stack unwinds
// the other catch blocks should be unaffected, in particular call_debugger should only be called before landing on this specific catch block
}
}
----
I've modified rt/deh2.d to allow it, it works great, but my implementation is hacky, and I'd like to poke the newsgroup for a better design:
class ThrowableSpecialUnwinding : Throwable {...}
void main(){
try{...}
catch(ThrowableSpecialUnwinding t){
//callbackBeforeUnwinding is called right before unwinding stack and entering this block
// it doesn't affect other catch blocks nor assumes anything about the caught exception which could be any Throwable.
// I've cheated here so casting back
auto real_t=cast(Throwable)cast(void*)t;
}
}
extern(C)
void callbackBeforeUnwinding(Throwable t){
call_debugger; //this could be calling a function pointer modifyable at runtime
}
The hacky part is here:
in rt/deh2.d, I changed:
if (_d_isbaseof(ci, pcb.type) )
to :
bool isSpecial = pcb.type== ThrowableSpecialUnwinding.classinfo && _d_isbaseof(ci, Throwable.classinfo);
if(isSpecial)
callbackBeforeUnwinding(cast(Throwable) *h);
if (_d_isbaseof(ci, pcb.type) || isSpecial) {/*will stack unwind here*/}