<div dir="ltr"><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">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. </div>
<div style="font-family:arial,sans-serif;font-size:12.727272033691406px">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)</div>
<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">This prevents attaching a debugger right before stack unwinding at the root of the program in the following scenario:</div>
<div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">----</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">
void fun(){</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">try{...}catch{...} </div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">// code that may throw and is usually caught in normal setting</div>
<div style="font-family:arial,sans-serif;font-size:12.727272033691406px">// occasionally some unusual exceptions/errors won't be caught</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">}<br>
</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">void call_debugger(){</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"> //raise signal so we can attach a debugger</div>
<div style="font-family:arial,sans-serif;font-size:12.727272033691406px">}</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">void main(){</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">
try{</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">  fun();</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">}</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">
catch(Throwable t){</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">  // we want to call call_debugger after an uncaught exception lands here but before stack unwinds, because most information is lost after stack unwinds</div>
<div style="font-family:arial,sans-serif;font-size:12.727272033691406px">  // the other catch blocks should be unaffected, in particular call_debugger should only be called before landing on this specific catch block</div>
<div style="font-family:arial,sans-serif;font-size:12.727272033691406px">}<br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">}</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">
----</div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><div style="font-family:arial,sans-serif;font-size:12.727272033691406px"><br></div><span style="font-family:arial,sans-serif;font-size:12.727272033691406px">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:</span><div style="font-family:arial,sans-serif;font-size:12.727272033691406px">
<br><div>class ThrowableSpecialUnwinding : Throwable {...}</div><div>void main(){</div><div>try{...}</div><div>catch(ThrowableSpecialUnwinding t){<br></div><div>//callbackBeforeUnwinding is called right before unwinding stack and entering this block</div>
<div>// it doesn't affect other catch blocks nor assumes anything about the caught exception which could be any Throwable.</div><div>// I've cheated here so casting back</div><div>auto real_t=cast(Throwable)cast(void*)t;</div>
<div>}<br></div><div>}</div><div><br></div><div>extern(C)</div><div>void callbackBeforeUnwinding(Throwable t){</div><div>call_debugger; //this could be calling a function pointer modifyable at runtime</div><div>}</div><div>
<br></div><div>The hacky part is here:</div><div>in rt/deh2.d, I changed:</div><div><br></div><div>if (_d_isbaseof(ci, pcb.type) )<br></div><div><br></div><div>to : </div><div><div><br></div><div>bool isSpecial = pcb.type== ThrowableSpecialUnwinding.classinfo && _d_isbaseof(ci, Throwable.classinfo);</div>
<div> if(isSpecial)</div><div>  callbackBeforeUnwinding(cast(Throwable) *h);</div></div><div><br></div><div>if (_d_isbaseof(ci, pcb.type) || isSpecial) {/*will stack unwind here*/}</div></div></div>