Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 540a6cb

Browse files
authored
Merge pull request #2035 from wilzbach/trap
Fix Issue 18220 - Allow `rt_trapexceptions` to be set from the CLI merged-on-behalf-of: Jacob Carlborg <jacob-carlborg@users.noreply.github.com>
2 parents 6121d40 + 6ca7779 commit 540a6cb

File tree

7 files changed

+112
-12
lines changed

7 files changed

+112
-12
lines changed

.circleci/run.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,11 @@ download() {
3131
}
3232

3333
install_deps() {
34+
sudo apt-get update
3435
if [ $MODEL -eq 32 ]; then
35-
sudo apt-get update
36-
sudo apt-get install g++-multilib
36+
sudo apt-get install -y g++-multilib
3737
fi
38+
sudo apt-get install -y gdb
3839

3940
download "https://dlang.org/install.sh" "https://nightlies.dlang.org/install.sh" "install.sh"
4041

changelog/exceptions-opt.dd

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Exception trapping can now be disabled via `--DRT-trapExceptions=0`
2+
3+
Previously it was only possible to disable the trapping of exception by setting
4+
the global variable `rt_trapExceptions` to `false`.
5+
Now you can, for example, immediately open `gdb` at the uncaught exception:
6+
7+
$(CONSOLE
8+
> gdb -ex run --args <my-program> --DRT-trapExceptions=0
9+
[Thread debugging using libthread_db enabled]
10+
Using host libthread_db library "/usr/lib/libthread_db.so.1".
11+
uncaught exception
12+
object.Exception@src/rt_trap_exceptions_drt.d(4): foo
13+
$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)$(NDASH)
14+
src/rt_trap_exceptions_drt.d:4 void rt_trap_exceptions_drt.test() [0x55591026]
15+
src/rt_trap_exceptions_drt.d:9 _Dmain [0x55591058]
16+
$(P)
17+
Program received signal SIGABRT, Aborted.
18+
0x00007ffff6e7b86b in raise () from /usr/lib/libc.so.6
19+
(gdb) bt full
20+
#0 0x00007ffff6e7b86b in raise () from /usr/lib/libc.so.6
21+
No symbol table info available.
22+
#1 0x00007ffff6e6640e in abort () from /usr/lib/libc.so.6
23+
No symbol table info available.
24+
#2 0x00005555555918cc in _d_throwdwarf (o=0x7ffff7ea4000) at src/rt/dwarfeh.d:233
25+
eh = 0x7ffff7fa4740
26+
refcount = 0
27+
r = 5
28+
#3 0x0000555555591027 in rt_trap_exceptions_drt.test() () at ../../src/object.d:2695
29+
innerLocal = 20
30+
#4 0x0000555555591059 in D main (args=...) at src/rt_trap_exceptions_drt.d:9
31+
myLocal = "bar"
32+
)
33+
34+
$(LINK2 http://arsdnet.net/this-week-in-d/2016-aug-07.html, This Week in D) for
35+
an in-depth explanation of `rt_trapExceptions`

src/core/internal/parseoptions.d

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,28 @@ bool parseOptions(CFG)(ref CFG cfg, string opt)
110110
return true;
111111
}
112112

113+
/**
114+
Parses an individual option `optname` value from a provided string `str`.
115+
The option type is given by the type `T` of the field `res` to which the parsed
116+
value will be written too.
117+
In case of an error, `errName` will be used to display an error message and
118+
the failure of the parsing will be indicated by a falsy return value.
119+
120+
For boolean values, '0/n/N' (false) or '1/y/Y' (true) are accepted.
121+
122+
Params:
123+
optname = name of the option to parse
124+
str = raw string to parse the option value from
125+
res = reference to the resulting data field that the option should be parsed too
126+
errName = full-text name of the option which should be displayed in case of errors
127+
128+
Returns: `false` if a parsing error happened.
129+
*/
130+
bool rt_parseOption(T)(const(char)[] optname, ref inout(char)[] str, ref T res, const(char)[] errName)
131+
{
132+
return parse(optname, str, res, errName);
133+
}
134+
113135
private:
114136

115137
bool optError(in char[] msg, in char[] name, const(char)[] errName)

src/rt/dmain2.d

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,17 +452,17 @@ extern (C) int _d_run_main(int argc, char **argv, MainFunc mainFunc)
452452
args = argsCopy[0..j];
453453
}
454454

455-
bool trapExceptions = rt_trapExceptions;
455+
auto useExceptionTrap = parseExceptionOptions();
456456

457457
version (Windows)
458458
{
459459
if (IsDebuggerPresent())
460-
trapExceptions = false;
460+
useExceptionTrap = false;
461461
}
462462

463463
void tryExec(scope void delegate() dg)
464464
{
465-
if (trapExceptions)
465+
if (useExceptionTrap)
466466
{
467467
try
468468
{
@@ -558,6 +558,18 @@ private void formatThrowable(Throwable t, scope void delegate(in char[] s) nothr
558558
}
559559
}
560560

561+
private auto parseExceptionOptions()
562+
{
563+
import rt.config : rt_configOption;
564+
import core.internal.parseoptions : rt_parseOption;
565+
const optName = "trapExceptions";
566+
auto option = rt_configOption(optName);
567+
auto trap = rt_trapExceptions;
568+
if (option.length)
569+
rt_parseOption(optName, option, trap, "");
570+
return trap;
571+
}
572+
561573
extern (C) void _d_print_throwable(Throwable t)
562574
{
563575
// On Windows, a console may not be present to print the output to.

src/rt/dwarfeh.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ extern(C) void _d_throwdwarf(Throwable o)
224224
case _URC_END_OF_STACK:
225225
/* Unwound the stack without encountering a catch clause.
226226
* In C++, this would mean call uncaught_exception().
227-
* In D, this can happen only if `rt_trapException` is cleared
227+
* In D, this can happen only if `rt_trapExceptions` is cleared
228228
* since otherwise everything is enclosed by a top-level
229229
* try/catch.
230230
*/

test/exceptions/Makefile

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
include ../common.mak
22

3-
TESTS:=stderr_msg unittest_assert invalid_memory_operation unknown_gc static_dtor future_message
3+
TESTS=stderr_msg unittest_assert invalid_memory_operation unknown_gc static_dtor future_message rt_trap_exceptions_drt
44

55
ifeq ($(OS)-$(BUILD),linux-debug)
6-
TESTS:=$(TESTS) line_trace rt_trap_exceptions
6+
TESTS+=line_trace rt_trap_exceptions
77
LINE_TRACE_DFLAGS:=-L--export-dynamic
88
endif
9+
ifeq ($(OS),linux)
10+
TESTS+=rt_trap_exceptions_drt_gdb
11+
endif
912
ifeq ($(OS)-$(BUILD),freebsd-debug)
10-
TESTS:=$(TESTS) line_trace
13+
TESTS+=line_trace
1114
LINE_TRACE_DFLAGS:=-L--export-dynamic
1215
endif
1316
ifeq ($(OS)-$(BUILD),dragonflybsd-debug)
14-
TESTS:=$(TESTS) line_trace
17+
TESTS+=line_trace
1518
LINE_TRACE_DFLAGS:=-L--export-dynamic
1619
endif
1720
ifeq ($(OS)-$(BUILD),osx-debug)
18-
TESTS:=$(TESTS) line_trace
21+
TESTS+=line_trace
1922
LINE_TRACE_DFLAGS:=
2023
endif
2124

2225
DIFF:=diff
2326
SED:=sed
27+
GDB:=gdb
2428

2529
.PHONY: all clean
2630
all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS)))
@@ -56,9 +60,25 @@ $(ROOT)/%.done: $(ROOT)/%
5660
fi
5761
@touch $@
5862

63+
$(ROOT)/rt_trap_exceptions_drt.done: STDERR_EXP="uncaught exception\nobject.Exception@rt_trap_exceptions_drt.d(4): exception"
64+
$(ROOT)/rt_trap_exceptions_drt.done: RUN_ARGS="--DRT-trapExceptions=0"
65+
$(ROOT)/rt_trap_exceptions_drt.done: NEGATE=!
66+
67+
68+
$(ROOT)/rt_trap_exceptions_drt_gdb.done: $(ROOT)/rt_trap_exceptions_drt
69+
@echo Testing rt_trap_exceptions_drt_gdb
70+
$(QUIET)$(TIMELIMIT) $(GDB) -ex run -ex 'bt full' -ex q --args $< --DRT-trapExceptions=0 \
71+
> $(ROOT)/rt_trap_exceptions_drt_gdb.output 2>&1 || true
72+
cat $(ROOT)/rt_trap_exceptions_drt_gdb.output
73+
grep "in D main (args=...) at src/rt_trap_exceptions_drt.d:9" > /dev/null < $(ROOT)/rt_trap_exceptions_drt_gdb.output
74+
grep 'myLocal' > /dev/null < $(ROOT)/rt_trap_exceptions_drt_gdb.output
75+
! grep "No stack." > /dev/null < $(ROOT)/rt_trap_exceptions_drt_gdb.output
76+
@touch $@
77+
5978
$(ROOT)/unittest_assert: DFLAGS+=-unittest
6079
$(ROOT)/line_trace: DFLAGS+=$(LINE_TRACE_DFLAGS)
61-
$(ROOT)/%: $(SRC)/%.d
80+
$(ROOT)/rt_trap_exceptions_drt: DFLAGS+=-g
81+
$(ROOT)/%: $(SRC)/%.d $(DMD) $(DRUNTIME)
6282
$(QUIET)$(DMD) $(DFLAGS) -of$@ $<
6383

6484
clean:
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
void test()
2+
{
3+
int innerLocal = 20;
4+
throw new Exception("foo");
5+
}
6+
void main(string[] args)
7+
{
8+
string myLocal = "bar";
9+
test();
10+
}

0 commit comments

Comments
 (0)