summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/beam_bif_load.c
diff options
context:
space:
mode:
authorJohn Högberg <john@erlang.org>2019-08-27 13:11:25 +0200
committerJohn Högberg <john@erlang.org>2019-09-16 14:21:25 +0200
commit40356bd2ae0e4f4c31204b3dd13d14541442f1a1 (patch)
treec3845959870988c148b2fbade94808bd1ebc0ae8 /erts/emulator/beam/beam_bif_load.c
parent20cf78bed119da47c66c3efd77c8199b424582b7 (diff)
downloaderlang-40356bd2ae0e4f4c31204b3dd13d14541442f1a1.tar.gz
erts: Refactor BIF tracing
This commit replaces our current BIF-specific tracing functionality with the general function/export tracing used for everything else, fixing a few longstanding issues: * BIFs that trapped to themselves, for example lists:reverse/2, would generate a call trace message for each trap but only a single return trace message. * BIFs that trapped elsewhere, like erlang:delete_module/1, would lose their return trace messages altogether. * Return/exception trace messages on tail calls would point at the function "above" the caller. * Call count tracing simply didn't work.
Diffstat (limited to 'erts/emulator/beam/beam_bif_load.c')
-rw-r--r--erts/emulator/beam/beam_bif_load.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index 587a61d814..a406e14741 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -847,8 +847,7 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2)
ep->addressv[code_ix] = (void*)ep->trampoline.not_loaded.deferred;
ep->trampoline.not_loaded.deferred = 0;
} else {
- if (ep->addressv[code_ix] == ep->trampoline.raw &&
- BeamIsOpCode(ep->trampoline.op, op_apply_bif)) {
+ if (ep->bif_table_index != -1) {
continue;
}
@@ -877,7 +876,7 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2)
if (ep == NULL || ep->info.mfa.module != BIF_ARG_1) {
continue;
}
- if (BeamIsOpCode(ep->trampoline.op, op_apply_bif)) {
+ if (ep->bif_table_index != -1) {
continue;
}
@@ -1891,10 +1890,7 @@ delete_code(Module* modp)
Export *ep = export_list(i, code_ix);
if (ep != NULL && (ep->info.mfa.module == module)) {
if (ep->addressv[code_ix] == ep->trampoline.raw) {
- if (BeamIsOpCode(ep->trampoline.op, op_apply_bif)) {
- continue;
- }
- else if (BeamIsOpCode(ep->trampoline.op, op_i_generic_breakpoint)) {
+ if (BeamIsOpCode(ep->trampoline.op, op_i_generic_breakpoint)) {
ERTS_LC_ASSERT(erts_thr_progress_is_blocking());
ASSERT(modp->curr.num_traced_exports > 0);
DBG_TRACE_MFA_P(&ep->info.mfa,
@@ -1906,6 +1902,12 @@ delete_code(Module* modp)
!erts_initialized);
}
}
+
+ if (ep->bif_table_index != -1 && ep->is_bif_traced) {
+ /* Code unloading kills both global and local call tracing. */
+ ep->is_bif_traced = 0;
+ }
+
ep->addressv[code_ix] = ep->trampoline.raw;
ep->trampoline.op = BeamOpCodeAddr(op_call_error_handler);
ep->trampoline.not_loaded.deferred = 0;