diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/doc/src/erlang.xml | 33 | ||||
-rw-r--r-- | erts/emulator/beam/break.c | 31 | ||||
-rw-r--r-- | erts/emulator/beam/dist.c | 34 | ||||
-rw-r--r-- | erts/emulator/beam/dist.h | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_binary.h | 7 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 4 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process_dump.c | 42 | ||||
-rw-r--r-- | erts/emulator/beam/external.c | 15 | ||||
-rw-r--r-- | erts/emulator/beam/global.h | 1 |
9 files changed, 111 insertions, 60 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index d205c24350..daf3002ec7 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -3361,25 +3361,6 @@ RealSystem = system + MissedSystem</code> monitored process resides). </p></item> </taglist> - <p>If an attempt is made to monitor a process on an older node - (where remote process monitoring is not implemented or - where remote process monitoring by registered name is not - implemented), the call fails with <c>badarg</c>.</p> - <note> - <p>The format of the <c>'DOWN'</c> message changed in ERTS - 5.2 (Erlang/OTP R9B) for monitoring - <em>by registered name</em>. Element <c>Object</c> of - the <c>'DOWN'</c> message could in earlier versions - sometimes be the process identifier of the monitored process and sometimes - be the registered name. Now element <c>Object</c> is - always a tuple consisting of the registered name and - the node name. Processes on new nodes (ERTS 5.2 - or higher versions) always get <c>'DOWN'</c> messages on - the new format even if they are monitoring processes on old - nodes. Processes on old nodes always get <c>'DOWN'</c> - messages on the old format.</p> - </note> - <taglist> <tag>Monitoring a <marker id="monitor_process"/><c>process</c></tag> <item> @@ -3387,7 +3368,19 @@ RealSystem = system + MissedSystem</code> process identified by <c><anno>Item</anno></c>, which can be a <c>pid()</c> (local or remote), an atom <c>RegisteredName</c> or a tuple <c>{RegisteredName, Node}</c> for a registered process, - located elsewhere.</p> + located elsewhere.</p> + + <note><p>Before ERTS 10.0 (OTP 21.0), monitoring a process could fail with + <c>badarg</c> if the monitored process resided on a primitive node + (such as erl_interface or jinterface), where remote process monitoring + is not implemented.</p> + <p>Now, such a call to <c>monitor</c> will instead succeed and a + monitor is created. But the monitor will only supervise the + connection. That is, a <c>{'DOWN', _, process, _, noconnection}</c> is + the only message that may be received, as the primitive node have no + way of reporting the status of the monitored process.</p> + </note> + </item> <tag>Monitoring a <marker id="monitor_port"/><c>port</c></tag> diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c index d9ee940662..2bfb481771 100644 --- a/erts/emulator/beam/break.c +++ b/erts/emulator/beam/break.c @@ -488,9 +488,7 @@ loaded(fmtfn_t to, void *to_arg) static void dump_attributes(fmtfn_t to, void *to_arg, byte* ptr, int size) { - while (size-- > 0) { - erts_print(to, to_arg, "%02X", *ptr++); - } + erts_print_base64(to, to_arg, ptr, size); erts_print(to, to_arg, "\n"); } @@ -848,7 +846,7 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args) } time(&now); - erts_cbprintf(to, to_arg, "=erl_crash_dump:0.4\n%s", ctime(&now)); + erts_cbprintf(to, to_arg, "=erl_crash_dump:0.5\n%s", ctime(&now)); if (file != NULL) erts_cbprintf(to, to_arg, "The error occurred in file %s, line %d\n", file, line); @@ -959,3 +957,28 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args) erts_fprintf(stderr,"done\n"); } +void +erts_print_base64(fmtfn_t to, void *to_arg, byte* src, Uint size) +{ + static const byte base64_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + while (size >= 3) { + erts_putc(to, to_arg, base64_chars[src[0] >> 2]); + erts_putc(to, to_arg, base64_chars[((src[0] & 0x03) << 4) | (src[1] >> 4)]); + erts_putc(to, to_arg, base64_chars[((src[1] & 0x0f) << 2) | (src[2] >> 6)]); + erts_putc(to, to_arg, base64_chars[src[2] & 0x3f]); + size -= 3; + src += 3; + } + if (size == 1) { + erts_putc(to, to_arg, base64_chars[src[0] >> 2]); + erts_putc(to, to_arg, base64_chars[(src[0] & 0x03) << 4]); + erts_print(to, to_arg, "=="); + } else if (size == 2) { + erts_putc(to, to_arg, base64_chars[src[0] >> 2]); + erts_putc(to, to_arg, base64_chars[((src[0] & 0x03) << 4) | (src[1] >> 4)]); + erts_putc(to, to_arg, base64_chars[(src[1] & 0x0f) << 2]); + erts_putc(to, to_arg, '='); + } +} diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c index 8593ad867a..7ff7462bf6 100644 --- a/erts/emulator/beam/dist.c +++ b/erts/emulator/beam/dist.c @@ -879,6 +879,13 @@ erts_dsig_send_m_exit(ErtsDSigData *dsdp, Eterm watcher, Eterm watched, DeclareTmpHeapNoproc(ctl_heap,6); int res; + if (~dsdp->dep->flags & (DFLAG_DIST_MONITOR | DFLAG_DIST_MONITOR_NAME)) { + /* + * Receiver does not support DOP_MONITOR_P_EXIT (see dsig_send_monitor) + */ + return ERTS_DSIG_SEND_OK; + } + UseTmpHeapNoproc(6); ctl = TUPLE5(&ctl_heap[0], make_small(DOP_MONITOR_P_EXIT), @@ -906,6 +913,16 @@ erts_dsig_send_monitor(ErtsDSigData *dsdp, Eterm watcher, Eterm watched, DeclareTmpHeapNoproc(ctl_heap,5); int res; + if (~dsdp->dep->flags & (DFLAG_DIST_MONITOR | DFLAG_DIST_MONITOR_NAME)) { + /* + * Receiver does not support DOP_MONITOR_P. + * Just avoid sending it and by doing that reduce this monitor + * to only supervise the connection. This will work for simple c-nodes + * with a 1-to-1 relation between "Erlang process" and OS-process. + */ + return ERTS_DSIG_SEND_OK; + } + UseTmpHeapNoproc(5); ctl = TUPLE4(&ctl_heap[0], make_small(DOP_MONITOR_P), @@ -928,6 +945,13 @@ erts_dsig_send_demonitor(ErtsDSigData *dsdp, Eterm watcher, DeclareTmpHeapNoproc(ctl_heap,5); int res; + if (~dsdp->dep->flags & (DFLAG_DIST_MONITOR | DFLAG_DIST_MONITOR_NAME)) { + /* + * Receiver does not support DOP_DEMONITOR_P (see dsig_send_monitor) + */ + return ERTS_DSIG_SEND_OK; + } + UseTmpHeapNoproc(5); ctl = TUPLE4(&ctl_heap[0], make_small(DOP_DEMONITOR_P), @@ -2337,10 +2361,10 @@ erts_dist_command(Port *prt, int initial_reds) ASSERT(ob); do { reds = erts_encode_ext_dist_header_finalize(ob, dep, flags, reds); - if (reds >= 0) { - last_finalized = ob; - ob = ob->next; - } + if (reds < 0) + break; + last_finalized = ob; + ob = ob->next; } while (ob); if (last_finalized) { /* @@ -2381,7 +2405,7 @@ erts_dist_command(Port *prt, int initial_reds) break; } ASSERT(&oq.first->data[0] <= oq.first->extp - && oq.first->extp < oq.first->ext_endp); + && oq.first->extp <= oq.first->ext_endp); size = (*send)(prt, oq.first); erts_atomic64_inc_nob(&dep->out); esdp->io.out += (Uint64) size; diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h index a96e39be89..ea4697815f 100644 --- a/erts/emulator/beam/dist.h +++ b/erts/emulator/beam/dist.h @@ -56,7 +56,9 @@ /* Additional optimistic flags when encoding toward pending connection */ #define DFLAG_DIST_HOPEFULLY (DFLAG_NO_MAGIC \ | DFLAG_EXPORT_PTR_TAG \ - | DFLAG_BIT_BINARIES) + | DFLAG_BIT_BINARIES \ + | DFLAG_DIST_MONITOR \ + | DFLAG_DIST_MONITOR_NAME) /* All flags that should be enabled when term_to_binary/1 is used. */ #define TERM_TO_BINARY_DFLAGS (DFLAG_EXTENDED_REFERENCES \ diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h index 05007e864e..46653a8580 100644 --- a/erts/emulator/beam/erl_binary.h +++ b/erts/emulator/beam/erl_binary.h @@ -363,8 +363,6 @@ erts_free_aligned_binary_bytes(byte* buf) # define CHICKEN_PAD (sizeof(void*) - 1) #endif -/* Caller must initialize 'refc' -*/ ERTS_GLB_INLINE Binary * erts_bin_drv_alloc_fnf(Uint size) { @@ -383,8 +381,6 @@ erts_bin_drv_alloc_fnf(Uint size) return res; } -/* Caller must initialize 'refc' -*/ ERTS_GLB_INLINE Binary * erts_bin_drv_alloc(Uint size) { @@ -401,9 +397,6 @@ erts_bin_drv_alloc(Uint size) return res; } - -/* Caller must initialize 'refc' -*/ ERTS_GLB_INLINE Binary * erts_bin_nrml_alloc(Uint size) { diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index d1018bab26..dbcc894ac9 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -544,6 +544,9 @@ void enif_clear_env(ErlNifEnv* env) ASSERT(p == menv->env.proc); ASSERT(p->common.id == ERTS_INVALID_PID); ASSERT(MBUF(p) == menv->env.heap_frag); + + free_tmp_objs(env); + if (MBUF(p) != NULL) { erts_cleanup_offheap(&MSO(p)); clear_offheap(&MSO(p)); @@ -555,7 +558,6 @@ void enif_clear_env(ErlNifEnv* env) menv->env.hp = menv->env.hp_end = HEAP_TOP(p); ASSERT(!is_offheap(&MSO(p))); - free_tmp_objs(env); } #ifdef DEBUG diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c index 0b7f361622..f562fc961b 100644 --- a/erts/emulator/beam/erl_process_dump.c +++ b/erts/emulator/beam/erl_process_dump.c @@ -51,6 +51,8 @@ static void stack_trace_dump(fmtfn_t to, void *to_arg, Eterm* sp); static void print_function_from_pc(fmtfn_t to, void *to_arg, BeamInstr* x); static void heap_dump(fmtfn_t to, void *to_arg, Eterm x); static void dump_binaries(fmtfn_t to, void *to_arg, Binary* root); +void erts_print_base64(fmtfn_t to, void *to_arg, + byte* src, Uint size); static void dump_externally(fmtfn_t to, void *to_arg, Eterm term); static void mark_literal(Eterm* ptr); static void init_literal_areas(void); @@ -193,6 +195,7 @@ dump_dist_ext(fmtfn_t to, void *to_arg, ErtsDistExternal *edep) else { byte *e; size_t sz; + if (!(edep->flags & ERTS_DIST_EXT_ATOM_TRANS_TAB)) erts_print(to, to_arg, "D0:"); else { @@ -210,12 +213,18 @@ dump_dist_ext(fmtfn_t to, void *to_arg, ErtsDistExternal *edep) else { ASSERT(*e == VERSION_MAGIC); } - erts_print(to, to_arg, "E%X:", sz); - if (edep->flags & ERTS_DIST_EXT_DFLAG_HDR) - erts_print(to, to_arg, "%02X", VERSION_MAGIC); - while (e < edep->ext_endp) - erts_print(to, to_arg, "%02X", *e++); + if (edep->flags & ERTS_DIST_EXT_DFLAG_HDR) { + byte sbuf[3]; + int i = 0; + + sbuf[i++] = VERSION_MAGIC; + while (i < sizeof(sbuf) && e < edep->ext_endp) { + sbuf[i++] = *e++; + } + erts_print_base64(to, to_arg, sbuf, i); + } + erts_print_base64(to, to_arg, e, edep->ext_endp - e); } } @@ -444,16 +453,13 @@ heap_dump(fmtfn_t to, void *to_arg, Eterm x) } else if (is_binary_header(hdr)) { Uint tag = thing_subtag(hdr); Uint size = binary_size(x); - Uint i; if (tag == HEAP_BINARY_SUBTAG) { byte* p; erts_print(to, to_arg, "Yh%X:", size); p = binary_bytes(x); - for (i = 0; i < size; i++) { - erts_print(to, to_arg, "%02X", p[i]); - } + erts_print_base64(to, to_arg, p, size); } else if (tag == REFC_BINARY_SUBTAG) { ProcBin* pb = (ProcBin *) binary_val(x); Binary* val = pb->val; @@ -596,16 +602,13 @@ static void dump_binaries(fmtfn_t to, void *to_arg, Binary* current) { while (current) { - long i; - long size = current->orig_size; + SWord size = current->orig_size; byte* bytes = (byte*) current->orig_bytes; erts_print(to, to_arg, "=binary:" PTR_FMT "\n", current); erts_print(to, to_arg, "%X:", size); - for (i = 0; i < size; i++) { - erts_print(to, to_arg, "%02X", bytes[i]); - } - erts_putc(to, to_arg, '\n'); + erts_print_base64(to, to_arg, bytes, size); + erts_putc(to, to_arg, '\n'); current = (Binary *) current->intern.flags; } } @@ -644,9 +647,7 @@ dump_externally(fmtfn_t to, void *to_arg, Eterm term) s = p = sbuf; erts_encode_ext(term, &p); erts_print(to, to_arg, "E%X:", p-s); - while (s < p) { - erts_print(to, to_arg, "%02X", *s++); - } + erts_print_base64(to, to_arg, sbuf, p-s); } /* @@ -802,16 +803,13 @@ dump_module_literals(fmtfn_t to, void *to_arg, ErtsLiteralArea* lit_area) } else if (is_binary_header(w)) { Uint tag = thing_subtag(w); Uint size = binary_size(term); - Uint i; if (tag == HEAP_BINARY_SUBTAG) { byte* p; erts_print(to, to_arg, "Yh%X:", size); p = binary_bytes(term); - for (i = 0; i < size; i++) { - erts_print(to, to_arg, "%02X", p[i]); - } + erts_print_base64(to, to_arg, p, size); } else if (tag == REFC_BINARY_SUBTAG) { ProcBin* pb = (ProcBin *) binary_val(term); Binary* val = pb->val; diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index f2e6399ad7..9cc5e71afa 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -383,6 +383,21 @@ Sint erts_encode_ext_dist_header_finalize(ErtsDistOutputBuf* ob, */ ASSERT(ep[0] == SMALL_TUPLE_EXT || ep[0] == LARGE_TUPLE_EXT); + if (~dflags & (DFLAG_DIST_MONITOR | DFLAG_DIST_MONITOR_NAME) + && ep[0] == SMALL_TUPLE_EXT + && ep[1] == 4 + && ep[2] == SMALL_INTEGER_EXT + && (ep[3] == DOP_MONITOR_P || + ep[3] == DOP_MONITOR_P_EXIT || + ep[3] == DOP_DEMONITOR_P)) { + /* + * Receiver does not support process monitoring. + * Suppress monitor control msg (see erts_dsig_send_monitor) + * by converting it to an empty (tick) packet. + */ + ob->ext_endp = ob->extp; + return reds; + } if (~dflags & (DFLAG_BIT_BINARIES | DFLAG_EXPORT_PTR_TAG | DFLAG_DIST_HDR_ATOM_CACHE)) { reds = transcode_dist_obuf(ob, dep, dflags, reds); diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h index 3dd3a60939..09207364eb 100644 --- a/erts/emulator/beam/global.h +++ b/erts/emulator/beam/global.h @@ -958,6 +958,7 @@ void process_info(fmtfn_t, void *); void print_process_info(fmtfn_t, void *, Process*); void info(fmtfn_t, void *); void loaded(fmtfn_t, void *); +void erts_print_base64(fmtfn_t to, void *to_arg, byte* src, Uint size); /* sighandler sys.c */ int erts_set_signal(Eterm signal, Eterm type); |