aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/bif.c
diff options
context:
space:
mode:
authorMaxim Fedorov <[email protected]>2017-12-13 12:22:59 -0800
committerMaxim Fedorov <[email protected]>2018-05-15 09:18:30 -0700
commitd23487f5daa4e898767b8171732c0fe0516bc1d0 (patch)
tree71f311edd44cc68ece707253d4b2a0435f04f4c0 /erts/emulator/beam/bif.c
parent3b3e2f46841e3e86c991be92d62cbb0360ca80e3 (diff)
downloadotp-d23487f5daa4e898767b8171732c0fe0516bc1d0.tar.gz
otp-d23487f5daa4e898767b8171732c0fe0516bc1d0.tar.bz2
otp-d23487f5daa4e898767b8171732c0fe0516bc1d0.zip
Throw 'system_limit' when distribution message size exceed INT_MAX instead of crashing emulator with 'Absurdly large distribution data buffer'
Exception must be thrown when buffer has been created and it's size is known. The actual buffer size is not known until the message has been encoded in ERTS_DSIG_SEND_PHASE_FIN. It would have been nice to abort before allocating and encoding, but in order to do that in a safe way the size calculation would need improvements. It is good enough to abort in the ERTS_DSIG_SEND_PHASE_FIN while we wait for the "fragmented distribution message" feature.
Diffstat (limited to 'erts/emulator/beam/bif.c')
-rw-r--r--erts/emulator/beam/bif.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 79244b8544..4c288d2892 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -1698,6 +1698,7 @@ ebif_bang_2(BIF_ALIST_2)
#define SEND_INTERNAL_ERROR (-6)
#define SEND_AWAIT_RESULT (-7)
#define SEND_YIELD_CONTINUE (-8)
+#define SEND_SYSTEM_LIMIT (-9)
static Sint remote_send(Process *p, DistEntry *dep,
@@ -1737,6 +1738,8 @@ static Sint remote_send(Process *p, DistEntry *dep,
res = SEND_YIELD_RETURN;
else if (code == ERTS_DSIG_SEND_CONTINUE)
res = SEND_YIELD_CONTINUE;
+ else if (code == ERTS_DSIG_SEND_TOO_LRG)
+ res = SEND_SYSTEM_LIMIT;
else
res = 0;
break;
@@ -2057,6 +2060,9 @@ BIF_RETTYPE send_3(BIF_ALIST_3)
case SEND_BADARG:
ERTS_BIF_PREP_ERROR(retval, p, BADARG);
break;
+ case SEND_SYSTEM_LIMIT:
+ ERTS_BIF_PREP_ERROR(retval, p, SYSTEM_LIMIT);
+ break;
case SEND_USER_ERROR:
ERTS_BIF_PREP_ERROR(retval, p, EXC_ERROR);
break;
@@ -2113,6 +2119,10 @@ static BIF_RETTYPE dsend_continue_trap_1(BIF_ALIST_1)
BUMP_ALL_REDS(BIF_P);
BIF_TRAP1(&dsend_continue_trap_export, BIF_P, BIF_ARG_1);
}
+ case ERTS_DSIG_SEND_TOO_LRG: { /*SEND_SYSTEM_LIMIT*/
+ erts_set_gc_state(BIF_P, 1);
+ BIF_ERROR(BIF_P, SYSTEM_LIMIT);
+ }
default:
erts_exit(ERTS_ABORT_EXIT, "dsend_continue_trap invalid result %d\n", (int)result);
break;
@@ -2170,6 +2180,9 @@ Eterm erl_send(Process *p, Eterm to, Eterm msg)
case SEND_BADARG:
ERTS_BIF_PREP_ERROR(retval, p, BADARG);
break;
+ case SEND_SYSTEM_LIMIT:
+ ERTS_BIF_PREP_ERROR(retval, p, SYSTEM_LIMIT);
+ break;
case SEND_USER_ERROR:
ERTS_BIF_PREP_ERROR(retval, p, EXC_ERROR);
break;