diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2021-10-05 12:17:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-05 12:17:10 +0200 |
commit | c782060a100352f383eadbe312685d984773f44c (patch) | |
tree | 75714ebb1da9227dd5e9afc0d7d6d909d421b86f | |
parent | 4c2e51b465fa2ffbb4c036b49f6f61272e6b99d7 (diff) | |
parent | 277224dcc622292b9956aee988685118cd9b0ae1 (diff) | |
download | erlang-c782060a100352f383eadbe312685d984773f44c.tar.gz |
Merge pull request #5252 from bjorng/bjorn/erts/gracefully-handle-old-beams
Provide more helpful error messages when loading old BEAM files
-rw-r--r-- | erts/emulator/beam/beam_file.c | 10 | ||||
-rw-r--r-- | erts/emulator/beam/beam_file.h | 1 | ||||
-rw-r--r-- | erts/emulator/beam/beam_load.c | 15 |
3 files changed, 18 insertions, 8 deletions
diff --git a/erts/emulator/beam/beam_file.c b/erts/emulator/beam/beam_file.c index c5f849ae3f..2148e037ad 100644 --- a/erts/emulator/beam/beam_file.c +++ b/erts/emulator/beam/beam_file.c @@ -747,6 +747,7 @@ beamfile_read(const byte *data, size_t size, BeamFile *beam) { MakeIffId('C', 'I', 'n', 'f'), /* 8 */ MakeIffId('L', 'i', 'n', 'e'), /* 9 */ MakeIffId('L', 'o', 'c', 'T'), /* 10 */ + MakeIffId('A', 't', 'o', 'm'), /* 11 */ }; static const int UTF8_ATOM_CHUNK = 0; @@ -762,6 +763,7 @@ beamfile_read(const byte *data, size_t size, BeamFile *beam) { #ifdef BEAMASM static const int LOC_CHUNK = 10; #endif + static const int OBSOLETE_ATOM_CHUNK = 11; static const int NUM_CHUNKS = sizeof(chunk_iffs) / sizeof(chunk_iffs[0]); @@ -791,7 +793,13 @@ beamfile_read(const byte *data, size_t size, BeamFile *beam) { } if (chunks[UTF8_ATOM_CHUNK].size == 0) { - error = BEAMFILE_READ_MISSING_ATOM_TABLE; + if (chunks[OBSOLETE_ATOM_CHUNK].size == 0) { + /* Old atom table chunk is also missing. */ + error = BEAMFILE_READ_MISSING_ATOM_TABLE; + } else { + /* Old atom table chunk table exists. (OTP 20 or earlier.) */ + error = BEAMFILE_READ_OBSOLETE_ATOM_TABLE; + } goto error; } else if (!parse_atom_chunk(beam, &chunks[UTF8_ATOM_CHUNK])) { error = BEAMFILE_READ_CORRUPT_ATOM_TABLE; diff --git a/erts/emulator/beam/beam_file.h b/erts/emulator/beam/beam_file.h index a7e0eda257..91b3d5e149 100644 --- a/erts/emulator/beam/beam_file.h +++ b/erts/emulator/beam/beam_file.h @@ -177,6 +177,7 @@ enum beamfile_read_result { /* Mandatory chunks */ BEAMFILE_READ_MISSING_ATOM_TABLE, + BEAMFILE_READ_OBSOLETE_ATOM_TABLE, BEAMFILE_READ_CORRUPT_ATOM_TABLE, BEAMFILE_READ_MISSING_CODE_CHUNK, BEAMFILE_READ_CORRUPT_CODE_CHUNK, diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c index e091b95bc5..aac381b522 100644 --- a/erts/emulator/beam/beam_load.c +++ b/erts/emulator/beam/beam_load.c @@ -47,6 +47,8 @@ Uint erts_total_code_size; static int load_code(LoaderState *stp); +#define PLEASE_RECOMPILE "please re-compile this module with an Erlang/OTP " ERLANG_OTP_RELEASE " compiler" + /**********************************************************************/ void init_load(void) @@ -128,6 +130,8 @@ erts_prepare_loading(Binary* magic, Process *c_p, Eterm group_leader, BeamLoadError0(stp, "corrupt file header"); case BEAMFILE_READ_MISSING_ATOM_TABLE: BeamLoadError0(stp, "missing atom table"); + case BEAMFILE_READ_OBSOLETE_ATOM_TABLE: + BeamLoadError0(stp, PLEASE_RECOMPILE); case BEAMFILE_READ_CORRUPT_ATOM_TABLE: BeamLoadError0(stp, "corrupt atom table"); case BEAMFILE_READ_MISSING_CODE_CHUNK: @@ -163,9 +167,8 @@ erts_prepare_loading(Binary* magic, Process *c_p, Eterm group_leader, if (stp->beam.code.max_opcode > MAX_GENERIC_OPCODE) { BeamLoadError2(stp, "This BEAM file was compiled for a later version" - " of the run-time system than " ERLANG_OTP_RELEASE ".\n" - " To fix this, please recompile this module with an " - ERLANG_OTP_RELEASE " compiler.\n" + " of the runtime system than the current (Erlang/OTP " ERLANG_OTP_RELEASE ").\n" + " To fix this, " PLEASE_RECOMPILE ".\n" " (Use of opcode %d; this emulator supports " "only up to %d.)", stp->beam.code.max_opcode, MAX_GENERIC_OPCODE); @@ -542,8 +545,7 @@ static int load_code(LoaderState* stp) * the instruction is obsolete. */ if (num_specific == 0 && gen_opc[tmp_op->op].transform == -1) { - BeamLoadError0(stp, "please re-compile this module with an " - ERLANG_OTP_RELEASE " compiler "); + BeamLoadError0(stp, PLEASE_RECOMPILE); } /* @@ -552,8 +554,7 @@ static int load_code(LoaderState* stp) */ switch (stp->genop->op) { case genop_too_old_compiler_0: - BeamLoadError0(stp, "please re-compile this module with an " - ERLANG_OTP_RELEASE " compiler"); + BeamLoadError0(stp, PLEASE_RECOMPILE); case genop_unsupported_guard_bif_3: { Eterm Mod = (Eterm) stp->genop->a[0].val; |