process_info(P,current_function) and HiPE (was Re: Bugs with hibernate/3 and HiPE)

Paul Guyot <>
Tue Sep 28 17:52:00 CEST 2010


Thank you for your e-mail.

> Please investigate:
> a) when and how BEAM updates current_function, and

c_p->current is either set to NULL or to a pointer to an {M,F,A} instruction triplet.

It is set:
- on context switch (which are always when entering a function)
- when calling a NIF
- on apply_bif
- on hibernate
- on various exception handlers and signaling.

> b) when you're allowed to call process_info(P, current_function) on
> a BEAM-mode function and what it returns; what if the target process
> is currently running? does it stop or does process_info then return
> stale data

I guess process_info returns stale data (simply the value of process->current).

> c) to what extent the hibernate test relies on the above

It is only used to figure out if the process is or is not hibernating. Indepently from the test, what I am mostly concerned with is that erts_hibernate sets current to {erlang,hibernate,3} and when the process wakes up, we should set it to a proper value (either the function being executed or NULL). If the wake up function is native, this does not happen and it remains {erlang,hibernate,3}.

The gen_server_SUITE:hibernate/1 test passes when simply setting c_p->current to I-3 in beam_emu.c's OpCase(hipe_trap_call), i.e. defining current to be the called native function. However, this looks weird because the data is definitely incorrect when the process is later switched out, waiting for a message. So I suggest to also clear current when exiting hipe_mode_switch in wait or suspend states. This is the content of the patch below. If you're fine with it, I'll submit it to 

+33.175000290 - 62 bis rue Gay-Lussac, 75005 Paris

diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 8a0e12d..ce49299 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -4850,6 +4850,7 @@ apply_bif_or_nif_epilogue:
          * ... remainder of original BEAM code
         ASSERT(I[-5] == (Uint) OpCode(i_func_info_IaaI));
+        c_p->current = I-3;
         c_p->hipe.ncallee = (void(*)(void)) I[-4];
         cmd = HIPE_MODE_SWITCH_CMD_CALL | (I[-1] << 8);
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
index e5de244..181f9c8 100644
--- a/erts/emulator/hipe/hipe_mode_switch.c
+++ b/erts/emulator/hipe/hipe_mode_switch.c
@@ -425,6 +425,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
          p->i = hipe_beam_pc_resume;
          p->arity = 0;
+         p->current = NULL;
          erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS);
          if (p->status != P_SUSPENDED)
@@ -445,6 +446,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
          p->i = hipe_beam_pc_resume;
          p->arity = 0;
          p->status = P_WAITING;
+         p->current = NULL;
          erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_MSG_RECEIVE);

More information about the erlang-bugs mailing list