summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2021-10-05 12:17:10 +0200
committerGitHub <noreply@github.com>2021-10-05 12:17:10 +0200
commitc782060a100352f383eadbe312685d984773f44c (patch)
tree75714ebb1da9227dd5e9afc0d7d6d909d421b86f
parent4c2e51b465fa2ffbb4c036b49f6f61272e6b99d7 (diff)
parent277224dcc622292b9956aee988685118cd9b0ae1 (diff)
downloaderlang-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.c10
-rw-r--r--erts/emulator/beam/beam_file.h1
-rw-r--r--erts/emulator/beam/beam_load.c15
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;