1 /** 2 * Entry point for exception handling support routines. 3 * 4 * There are three style of exception handling being supported by DMD: 5 * DWARF, Win32, and Win64. The Win64 code also supports POSIX. 6 * Support for those scheme is in `rt.dwarfeh`, `rt.deh_win32`, and 7 * `rt.deh_win64_posix`, respectively, and publicly imported here. 8 * 9 * When an exception is thrown by the user, the compiler translates 10 * code like `throw e;` into either `_d_throwdwarf` (for DWARF exceptions) 11 * or `_d_throwc` (Win32 / Win64), with the `Exception` object as argument. 12 * 13 * During those functions' handling, they eventually call `_d_createTrace`, 14 * which will store inside the `Exception` object the return of 15 * `_d_traceContext`, which is an object implementing `Throwable.TraceInfo`. 16 * `_d_traceContext` is a configurable hook, and by default will call 17 * `core.runtime : defaultTraceHandler`, which itself will call `backtrace` 18 * or something similar to store an array of stack frames (`void*` pointers) 19 * in the object it returns. 20 * Note that `defaultTraceHandler` returns a GC-allocated instance, 21 * hence a GC allocation can happen in the middle of throwing an `Exception`. 22 * 23 * The `Throwable.TraceInfo`-implementing should not resolves function names, 24 * file and line number until its `opApply` function is called, avoiding the 25 * overhead of reading the debug infos until the user call `toString`. 26 * If the user only calls `Throwable.message` (or use `Throwable.msg` directly), 27 * only the overhead of `backtrace` will be paid, which is minimal enouh. 28 * 29 * Copyright: Copyright Digital Mars 1999 - 2020. 30 * License: Distributed under the 31 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). 32 * (See accompanying file LICENSE) 33 * Authors: Walter Bright 34 * Source: $(DRUNTIMESRC rt/deh.d) 35 */ 36 module rt.deh; 37 38 extern (C) 39 { 40 Throwable.TraceInfo _d_traceContext(void* ptr = null); 41 Throwable.TraceDeallocator rt_getTraceDeallocator(); 42 void _d_createTrace(Throwable t, void* context) 43 { 44 if (t !is null && t.info is null && 45 cast(byte*) t !is typeid(t).initializer.ptr) 46 { 47 t.info = _d_traceContext(context); 48 t.infoDeallocator = rt_getTraceDeallocator(); 49 } 50 } 51 } 52 53 version (Win32) 54 public import rt.deh_win32; 55 else version (Win64) 56 public import rt.deh_win64_posix; 57 else version (Posix) 58 public import rt.deh_win64_posix; 59 else 60 static assert (0, "Unsupported architecture");