diff options
author | Björn Gustavsson <[email protected]> | 2017-05-08 12:36:15 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2017-05-08 12:36:15 +0200 |
commit | 83f73246b6942fc78bc4e7af69cb900ce1aea796 (patch) | |
tree | 28deeccb770996975593a34f61ae1eff48a62860 | |
parent | 66c23a4fa9f92eb510cf55daa17822c926d7c147 (diff) | |
parent | ff94c59ca65ab3f4d9a1660e64ae31ed2232a5c2 (diff) | |
download | otp-83f73246b6942fc78bc4e7af69cb900ce1aea796.tar.gz otp-83f73246b6942fc78bc4e7af69cb900ce1aea796.tar.bz2 otp-83f73246b6942fc78bc4e7af69cb900ce1aea796.zip |
Merge pull request #1443 from bjorng/bjorn/mend-fvalue-leak/OTP-14255
Mend p->fvalue leak
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 2 | ||||
-rw-r--r-- | erts/emulator/test/hipe_SUITE.erl | 68 | ||||
-rw-r--r-- | erts/emulator/test/hipe_SUITE_data/trycatch_1.erl | 14 | ||||
-rw-r--r-- | erts/emulator/test/hipe_SUITE_data/trycatch_2.erl | 10 | ||||
-rw-r--r-- | erts/emulator/test/hipe_SUITE_data/trycatch_3.erl | 9 |
5 files changed, 103 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 311bb94242..a90e6a0ba8 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -1814,6 +1814,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) c_p->catches--; make_blank(yb(Arg(0))); if (is_non_value(r(0))) { + c_p->fvalue = NIL; if (x(1) == am_throw) { r(0) = x(2); } else { @@ -1843,6 +1844,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array) c_p->catches--; make_blank(yb(Arg(0))); if (is_non_value(r(0))) { + c_p->fvalue = NIL; r(0) = x(1); x(1) = x(2); x(2) = x(3); diff --git a/erts/emulator/test/hipe_SUITE.erl b/erts/emulator/test/hipe_SUITE.erl index 0b44dd7fb7..5083f01f34 100644 --- a/erts/emulator/test/hipe_SUITE.erl +++ b/erts/emulator/test/hipe_SUITE.erl @@ -22,6 +22,7 @@ -export([all/0 ,t_copy_literals/1 ,t_purge/1 + ,t_trycatch/1 ]). all() -> @@ -29,6 +30,7 @@ all() -> undefined -> {skip, "HiPE is disabled"}; _ -> [t_copy_literals ,t_purge + ,t_trycatch ] end. @@ -118,3 +120,69 @@ t_purge(Config) when is_list(Config) -> call(Pid, Call) -> Pid ! {Call, self()}, receive {Pid, Res} -> Res end. + +t_trycatch(Config) -> + DataDir = proplists:get_value(data_dir, Config), + Files = ["trycatch_1.erl","trycatch_2.erl","trycatch_3.erl"], + Sources0 = [filename:join(DataDir, Src) || Src <- Files], + Sources = trycatch_combine(Sources0), + t_trycatch_1(Sources). + +t_trycatch_1([S|Ss]) -> + io:format("~p", [S]), + compile_and_load(S), + call_trycatch(try_catch), + call_trycatch(plain_catch), + io:nl(), + t_trycatch_1(Ss); +t_trycatch_1([]) -> + ok. + +trycatch_combine([N|Ns]) -> + Combined = trycatch_combine(Ns), + lists:append([[[{N,[]}|C],[{N,[native]},C]] || C <- Combined]); +trycatch_combine([]) -> + [[]]. + +call_trycatch(Func) -> + case do_call_trycatch(error, Func, {error,whatever}) of + {error,whatever,[{trycatch_3,three,1,_}|_]} -> + ok + end, + case do_call_trycatch(error, Func, fc) of + {error,function_clause,[{trycatch_3,three,[fc],_}|_]} -> + ok; + {error,function_clause,[{trycatch_3,three,1,_}|_]} -> + ok + end, + case do_call_trycatch(throw, Func, {throw,{a,b}}) of + {throw,{a,b},[{trycatch_3,three,1,_}|_]} -> + ok + end, + case do_call_trycatch(exit, Func, {exit,{a,b,c}}) of + {exit,{a,b,c},[{trycatch_3,three,1,_}|_]} -> + ok + end, + ok. + +do_call_trycatch(_Class, try_catch, Argument) -> + trycatch_1:one_try_catch(Argument); +do_call_trycatch(error, plain_catch, Argument) -> + {{'EXIT',{Reason,Stk}},Stk} = trycatch_1:one_plain_catch(Argument), + {error,Reason,Stk}; +do_call_trycatch(throw, plain_catch, Argument) -> + {Reason,Stk} = trycatch_1:one_plain_catch(Argument), + {throw,Reason,Stk}; +do_call_trycatch(exit, plain_catch, Argument) -> + {{'EXIT',Reason},Stk} = trycatch_1:one_plain_catch(Argument), + {exit,Reason,Stk}. + +compile_and_load(Sources) -> + _ = [begin + {ok,Mod,Bin} = compile:file(Src, [binary,report|Opts]), + code:purge(Mod), + code:delete(Mod), + code:purge(Mod), + {module,Mod} = code:load_binary(Mod, atom_to_list(Mod), Bin) + end || {Src,Opts} <- Sources], + ok. diff --git a/erts/emulator/test/hipe_SUITE_data/trycatch_1.erl b/erts/emulator/test/hipe_SUITE_data/trycatch_1.erl new file mode 100644 index 0000000000..702b14b5b9 --- /dev/null +++ b/erts/emulator/test/hipe_SUITE_data/trycatch_1.erl @@ -0,0 +1,14 @@ +-module(trycatch_1). +-export([one_try_catch/1,one_plain_catch/1]). + +one_try_catch(Term) -> + try + trycatch_2:two(Term) + catch + C:R -> + Stk = erlang:get_stacktrace(), + {C,R,Stk} + end. + +one_plain_catch(Term) -> + {catch trycatch_2:two(Term),erlang:get_stacktrace()}. diff --git a/erts/emulator/test/hipe_SUITE_data/trycatch_2.erl b/erts/emulator/test/hipe_SUITE_data/trycatch_2.erl new file mode 100644 index 0000000000..ffac420197 --- /dev/null +++ b/erts/emulator/test/hipe_SUITE_data/trycatch_2.erl @@ -0,0 +1,10 @@ +-module(trycatch_2). +-export([two/1]). + +two(Term) -> + Res = trycatch_3:three(Term), + foo(), + Res. + +foo() -> + ok. diff --git a/erts/emulator/test/hipe_SUITE_data/trycatch_3.erl b/erts/emulator/test/hipe_SUITE_data/trycatch_3.erl new file mode 100644 index 0000000000..578fa0e87e --- /dev/null +++ b/erts/emulator/test/hipe_SUITE_data/trycatch_3.erl @@ -0,0 +1,9 @@ +-module(trycatch_3). +-export([three/1]). + +three({error,Term}) -> + error(Term); +three({throw,Term}) -> + throw(Term); +three({exit,Term}) -> + exit(Term). |