aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/exception_SUITE.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-09-30 07:48:34 +0200
committerBjörn Gustavsson <[email protected]>2017-09-30 09:43:33 +0200
commit9a50a5d5fc1c74d91efad74e1cb3e78f38e2b75c (patch)
tree5999ee43220e0c7823f4651b1f3b5731825804b3 /erts/emulator/test/exception_SUITE.erl
parentd0875a87fc59bea515294455b2047040118f3a7e (diff)
downloadotp-9a50a5d5fc1c74d91efad74e1cb3e78f38e2b75c.tar.gz
otp-9a50a5d5fc1c74d91efad74e1cb3e78f38e2b75c.tar.bz2
otp-9a50a5d5fc1c74d91efad74e1cb3e78f38e2b75c.zip
Point out the correct line number in stack traces
Sometimes the line number in a stack trace could be wrong, for example for this code: t() -> Res = id(x), %<== Wrong line number. Res + 1. id(I) -> I. The line number pointed out in the stack trace would be the line before the line where the exception occurred. The reason is the way the increment instruction instruction is implemented: OpCase(i_increment_rWtd): { increment_reg_val = r(0); } I -= 1; goto increment__execute; OpCase(i_increment_xWtd): { increment_reg_val = xb(I[1]); } goto increment__execute; increment__execute: /* Common code for increment */ . . . (The implementation in OTP 20 is similar, but hand-coded directly in beam_emu.c instead of generated.) The instruction i_increment_rWtd decrements the instruction pointer (I) before jumping to the common code. That means that I points *before* the 'increment' instruction. If there is a 'line' instruction directly before the 'increment' instruction (as there is in this example), the instruction pointer will point before that line. Thus the previous line will be picked up instead. To eliminate this bug, we must never decrement the instruction pointer. Instead, we can increment the other (longer) instructions in the same group of combined instructions: OpCase(i_increment_rWtd): { increment_reg_val = r(0); } goto increment__execute; OpCase(i_increment_xWtd): { increment_reg_val = xb(I[1]); } I += 1; goto increment__execute; increment__execute: /* Common code for increment */ . . . Also fix a bug that was only a potential bug when ddaed7774eb0a introduced relative jumps, but is now a real bug. See the added comment for SET_I_REL() in macros.tab.
Diffstat (limited to 'erts/emulator/test/exception_SUITE.erl')
-rw-r--r--erts/emulator/test/exception_SUITE.erl21
1 files changed, 21 insertions, 0 deletions
diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl
index e473a10be7..0f27251fcb 100644
--- a/erts/emulator/test/exception_SUITE.erl
+++ b/erts/emulator/test/exception_SUITE.erl
@@ -662,6 +662,15 @@ line_numbers(Config) when is_list(Config) ->
{?MODULE,line_numbers,1,_}|_]}} =
(catch applied_bif_2()),
+ {'EXIT',{badarith,
+ [{?MODULE,increment1,1,[{file,"increment.erl"},{line,45}]},
+ {?MODULE,line_numbers,1,_}|_]}} =
+ (catch increment1(x)),
+ {'EXIT',{badarith,
+ [{?MODULE,increment2,1,[{file,"increment.erl"},{line,48}]},
+ {?MODULE,line_numbers,1,_}|_]}} =
+ (catch increment2(x)),
+
ok.
id(I) -> I.
@@ -762,3 +771,15 @@ applied_bif_2() -> %Line 8
R = process_info(self(), current_location), %Line 9
fail = R, %Line 10
ok. %Line 11
+
+%% The increment instruction used to decrement the instruction
+%% pointer, which would cause the line number in a stack trace to
+%% be the previous line number.
+
+-file("increment.erl", 42).
+increment1(Arg) -> %Line 43
+ Res = id(Arg), %Line 44
+ Res + 1. %Line 45
+increment2(Arg) -> %Line 46
+ _ = id(Arg), %Line 47
+ Arg + 1. %Line 48