diff options
author | Björn Gustavsson <[email protected]> | 2011-03-04 14:10:39 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2011-03-04 14:29:59 +0100 |
commit | 22cfda86e15600f8b3622c7ed4101366199e1843 (patch) | |
tree | ec70d4facd6c53bef9f5d123c9b3c266b4c0f2f5 /erts | |
parent | 03ee5e80434aa2c86196832a8b9eaf78fe2e8f5d (diff) | |
download | otp-22cfda86e15600f8b3622c7ed4101366199e1843.tar.gz otp-22cfda86e15600f8b3622c7ed4101366199e1843.tar.bz2 otp-22cfda86e15600f8b3622c7ed4101366199e1843.zip |
erts: Initialize register that may be referenced by garbage collection
The call_fun() function in the BEAM emulator is supposed to
to put the fun term in the x register following the actual arguments
and environment for the fun. But if the fun is not loaded and
a call to the error_handler:undefined_lambda/3 function is set up,
the x(3) register will not be initialized.
The lack of initialization is very unlikely to cause a problem
in practice, because all of the following things must happen:
1) An unloaded fun must be called (i.e. the fun must have
been received from another node or from a file or dets table).
2) The process must be scheduled out before the call to the
error_handler:undefined_lambda/3 function can take place.
3) The process must be garbage collected before the process
is scheduled in.
4) The x(3) register must contain a stale cons or box pointer
that happens to point into the the heap of the currently
executing process. (Because of the literal pool, the GC will
never copy anything that is outside of the heap.)
I was not able to write a test case that would force an
emulator crash.
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index a4fb454481..e96014c665 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -6398,6 +6398,7 @@ call_fun(Process* p, /* Current process. */ reg[0] = module; reg[1] = fun; reg[2] = args; + reg[3] = NIL; return ep->address; } } |