aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/bif.c58
-rw-r--r--erts/emulator/beam/break.c41
-rw-r--r--erts/emulator/beam/erl_bif_info.c3
-rw-r--r--erts/emulator/beam/erl_db_util.c2
-rw-r--r--erts/emulator/beam/erl_trace.c44
-rw-r--r--erts/emulator/beam/erl_trace.h2
-rw-r--r--erts/emulator/beam/global.h2
-rw-r--r--erts/emulator/beam/utils.c55
8 files changed, 78 insertions, 129 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 457910f913..000397e790 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -4701,6 +4701,9 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
return erts_bind_schedulers(BIF_P, BIF_ARG_2);
} else if (ERTS_IS_ATOM_STR("erts_alloc", BIF_ARG_1)) {
return erts_alloc_set_dyn_param(BIF_P, BIF_ARG_2);
+ } else if (ERTS_IS_ATOM_STR("system_logger", BIF_ARG_1)) {
+ Eterm res = erts_set_system_logger(BIF_ARG_2);
+ if (is_value(res)) BIF_RET(res);
}
error:
BIF_ERROR(BIF_P, BADARG);
@@ -5203,61 +5206,6 @@ erts_call_dirty_bif(ErtsSchedulerData *esdp, Process *c_p, BeamInstr *I, Eterm *
return exiting;
}
-
-
-#ifdef HARDDEBUG
-/*
-You'll need this line in bif.tab to be able to use this debug bif
-
-bif erlang:send_to_logger/2
-
-*/
-BIF_RETTYPE send_to_logger_2(BIF_ALIST_2)
-{
- byte *buf;
- ErlDrvSizeT len;
- if (!is_atom(BIF_ARG_1) || !(is_list(BIF_ARG_2) ||
- is_nil(BIF_ARG_1))) {
- BIF_ERROR(BIF_P,BADARG);
- }
- if (erts_iolist_size(BIF_ARG_2, &len) != 0)
- BIF_ERROR(BIF_P,BADARG);
- else if (len == 0)
- buf = "";
- else {
-#ifdef DEBUG
- ErlDrvSizeT len2;
-#endif
- buf = (byte *) erts_alloc(ERTS_ALC_T_TMP, len+1);
-#ifdef DEBUG
- len2 =
-#else
- (void)
-#endif
- erts_iolist_to_buf(BIF_ARG_2, buf, len);
- ASSERT(len2 == len);
- buf[len] = '\0';
- switch (BIF_ARG_1) {
- case am_info:
- erts_send_info_to_logger(BIF_P->group_leader, buf, len);
- break;
- case am_warning:
- erts_send_warning_to_logger(BIF_P->group_leader, buf, len);
- break;
- case am_error:
- erts_send_error_to_logger(BIF_P->group_leader, buf, len);
- break;
- default:
- {
- BIF_ERROR(BIF_P,BADARG);
- }
- }
- erts_free(ERTS_ALC_T_TMP, (void *) buf);
- }
- BIF_RET(am_true);
-}
-#endif /* HARDDEBUG */
-
BIF_RETTYPE get_module_info_1(BIF_ALIST_1)
{
Eterm ret = erts_module_info_0(BIF_P, BIF_ARG_1);
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 9ff52c92b8..92009c2345 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -82,7 +82,7 @@ process_info(fmtfn_t to, void *to_arg)
* they are most likely just created and has invalid data
*/
if (!ERTS_PROC_IS_EXITING(p) && p->heap != NULL)
- print_process_info(to, to_arg, p);
+ print_process_info(to, to_arg, p, 0);
}
}
@@ -101,7 +101,7 @@ process_killer(void)
rp = erts_pix2proc(i);
if (rp && rp->i != ENULL) {
int br;
- print_process_info(ERTS_PRINT_STDOUT, NULL, rp);
+ print_process_info(ERTS_PRINT_STDOUT, NULL, rp, 0);
erts_printf("(k)ill (n)ext (r)eturn:\n");
while(1) {
if ((j = sys_get_key(0)) <= 0)
@@ -199,13 +199,14 @@ static void doit_print_monitor(ErtsMonitor *mon, void *vpcontext)
/* Display info about an individual Erlang process */
void
-print_process_info(fmtfn_t to, void *to_arg, Process *p)
+print_process_info(fmtfn_t to, void *to_arg, Process *p, ErtsProcLocks orig_locks)
{
int garbing = 0;
int running = 0;
Sint len;
struct saved_calls *scb;
erts_aint32_t state;
+ ErtsProcLocks locks = orig_locks;
/* display the PID */
erts_print(to, to_arg, "=proc:%T\n", p->common.id);
@@ -222,6 +223,22 @@ print_process_info(fmtfn_t to, void *to_arg, Process *p)
| ERTS_PSFLG_DIRTY_RUNNING))
running = 1;
+ if (!(locks & ERTS_PROC_LOCK_MAIN)) {
+ locks |= ERTS_PROC_LOCK_MAIN;
+ if (ERTS_IS_CRASH_DUMPING && running) {
+ if (erts_proc_trylock(p, locks)) {
+ /* crash dumping and main lock taken, this probably means that
+ the process is doing a GC on a dirty-scheduler... so we cannot
+ do erts_proc_sig_fetch as that would potentially cause a segfault */
+ locks = 0;
+ }
+ } else {
+ erts_proc_lock(p, locks);
+ }
+ } else {
+ ERTS_ASSERT(locks == ERTS_PROC_LOCK_MAIN && "Only main lock should be held");
+ }
+
/*
* If the process is registered as a global process, display the
* registered name
@@ -251,13 +268,19 @@ print_process_info(fmtfn_t to, void *to_arg, Process *p)
erts_print(to, to_arg, "Spawned by: %T\n", p->parent);
- erts_proc_lock(p, ERTS_PROC_LOCK_MSGQ);
- len = erts_proc_sig_fetch(p);
- erts_proc_unlock(p, ERTS_PROC_LOCK_MSGQ);
+ if (locks & ERTS_PROC_LOCK_MAIN) {
+ erts_proc_lock(p, ERTS_PROC_LOCK_MSGQ);
+ len = erts_proc_sig_fetch(p);
+ erts_proc_unlock(p, ERTS_PROC_LOCK_MSGQ);
+ } else {
+ len = p->sig_qs.len;
+ }
erts_print(to, to_arg, "Message queue length: %d\n", len);
- /* display the message queue only if there is anything in it */
- if (!ERTS_IS_CRASH_DUMPING && p->sig_qs.first != NULL && !garbing) {
+ /* display the message queue only if there is anything in it
+ and we can do it safely */
+ if (!ERTS_IS_CRASH_DUMPING && p->sig_qs.first != NULL && !garbing
+ && (locks & ERTS_PROC_LOCK_MAIN)) {
erts_print(to, to_arg, "Message queue: [");
ERTS_FOREACH_SIG_PRIVQS(
p, mp,
@@ -357,6 +380,8 @@ print_process_info(fmtfn_t to, void *to_arg, Process *p)
/* Display all states */
erts_print(to, to_arg, "Internal State: ");
erts_dump_extended_process_state(to, to_arg, state);
+
+ erts_proc_unlock(p, locks & ~orig_locks);
}
static void
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 7fada0d548..6137edef1b 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -3139,6 +3139,8 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1)
DECL_AM(tag);
BIF_RET(AM_tag);
#endif
+ } else if (ERTS_IS_ATOM_STR("system_logger", BIF_ARG_1)) {
+ BIF_RET(erts_get_system_logger());
}
BIF_ERROR(BIF_P, BADARG);
@@ -4608,6 +4610,7 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
}
}
else if (ERTS_IS_ATOM_STR("broken_halt", BIF_ARG_1)) {
+ erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
broken_halt_test(BIF_ARG_2);
}
else if (ERTS_IS_ATOM_STR("unique_monotonic_integer_state", BIF_ARG_1)) {
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index f1d47326b4..e2c029c244 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -2470,7 +2470,7 @@ restart:
case matchProcessDump: {
erts_dsprintf_buf_t *dsbufp = erts_create_tmp_dsbuf(0);
ASSERT(c_p == self);
- print_process_info(ERTS_PRINT_DSBUF, (void *) dsbufp, c_p);
+ print_process_info(ERTS_PRINT_DSBUF, (void *) dsbufp, c_p, ERTS_PROC_LOCK_MAIN);
*esp++ = new_binary(build_proc, (byte *)dsbufp->str,
dsbufp->str_len);
erts_destroy_tmp_dsbuf(dsbufp);
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 2350d4c02f..701fb38147 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -72,6 +72,7 @@ static ErtsTracer default_port_tracer;
static Eterm system_monitor;
static Eterm system_profile;
+static erts_aint_t system_logger;
#ifdef HAVE_ERTS_NOW_CPU
int erts_cpu_timestamp;
@@ -340,6 +341,7 @@ void erts_init_trace(void) {
default_port_trace_flags = F_INITIAL_TRACE_FLAGS;
default_port_tracer = erts_tracer_nil;
system_seq_tracer = erts_tracer_nil;
+ erts_atomic_init_nob(&system_logger, am_logger);
init_sys_msg_dispatcher();
init_tracer_nif();
}
@@ -2027,10 +2029,24 @@ enqueue_sys_msg(enum ErtsSysMsgType type,
erts_mtx_unlock(&smq_mtx);
}
+Eterm
+erts_get_system_logger(void)
+{
+ return (Eterm)erts_atomic_read_nob(&system_logger);
+}
+
+Eterm
+erts_set_system_logger(Eterm logger)
+{
+ if (logger != am_logger && logger != am_undefined && !is_internal_pid(logger))
+ return THE_NON_VALUE;
+ return (Eterm)erts_atomic_xchg_nob(&system_logger, logger);
+}
+
void
erts_queue_error_logger_message(Eterm from, Eterm msg, ErlHeapFragment *bp)
{
- enqueue_sys_msg(SYS_MSG_TYPE_ERRLGR, from, am_logger, msg, bp);
+ enqueue_sys_msg(SYS_MSG_TYPE_ERRLGR, from, erts_get_system_logger(), msg, bp);
}
void
@@ -2271,7 +2287,7 @@ sys_msg_dispatcher_func(void *unused)
}
break;
case SYS_MSG_TYPE_ERRLGR:
- receiver = am_logger;
+ receiver = smqp->to;
break;
default:
receiver = NIL;
@@ -2285,8 +2301,15 @@ sys_msg_dispatcher_func(void *unused)
if (is_internal_pid(receiver)) {
proc = erts_pid2proc(NULL, 0, receiver, proc_locks);
if (!proc) {
- /* Bad tracer */
- goto failure;
+ if (smqp->type == SYS_MSG_TYPE_ERRLGR) {
+ /* Bad logger process, send to kernel 'logger' process */
+ erts_set_system_logger(am_logger);
+ receiver = erts_get_system_logger();
+ goto logger;
+ } else {
+ /* Bad tracer */
+ goto failure;
+ }
}
else {
ErtsMessage *mp;
@@ -2299,9 +2322,9 @@ sys_msg_dispatcher_func(void *unused)
#endif
erts_proc_unlock(proc, proc_locks);
}
- }
- else if (receiver == am_logger) {
- proc = erts_whereis_process(NULL,0,receiver,proc_locks,0);
+ } else if (receiver == am_logger) {
+ logger:
+ proc = erts_whereis_process(NULL,0,am_logger,proc_locks,0);
if (!proc)
goto failure;
else if (smqp->from == proc->common.id)
@@ -2309,7 +2332,10 @@ sys_msg_dispatcher_func(void *unused)
else
goto queue_proc_msg;
}
- else if (is_internal_port(receiver)) {
+ else if (receiver == am_undefined) {
+ goto drop_sys_msg;
+ }
+ else if (is_internal_port(receiver)) {
port = erts_thr_id2port_sflgs(receiver,
ERTS_PORT_SFLGS_INVALID_TRACER_LOOKUP);
if (!port)
@@ -2366,7 +2392,7 @@ erts_foreach_sys_msg_in_q(void (*func)(Eterm,
to = erts_get_system_profile();
break;
case SYS_MSG_TYPE_ERRLGR:
- to = am_logger;
+ to = erts_get_system_logger();
break;
default:
to = NIL;
diff --git a/erts/emulator/beam/erl_trace.h b/erts/emulator/beam/erl_trace.h
index bccf31606e..b7844d1cb0 100644
--- a/erts/emulator/beam/erl_trace.h
+++ b/erts/emulator/beam/erl_trace.h
@@ -94,6 +94,8 @@ void erts_foreach_sys_msg_in_q(void (*func)(Eterm,
Eterm,
Eterm,
ErlHeapFragment *));
+Eterm erts_set_system_logger(Eterm);
+Eterm erts_get_system_logger(void);
void erts_queue_error_logger_message(Eterm, Eterm, ErlHeapFragment *);
void erts_send_sys_msg_proc(Eterm, Eterm, Eterm, ErlHeapFragment *);
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index f1c6adeedd..36b753ca9c 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -962,7 +962,7 @@ void init_break_handler(void);
void erts_set_ignore_break(void);
void erts_replace_intr(void);
void process_info(fmtfn_t, void *);
-void print_process_info(fmtfn_t, void *, Process*);
+void print_process_info(fmtfn_t, void *, Process*, ErtsProcLocks);
void info(fmtfn_t, void *);
void loaded(fmtfn_t, void *);
void erts_print_base64(fmtfn_t to, void *to_arg, byte* src, Uint size);
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 1a6bcbb66e..a231638b50 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -4788,58 +4788,3 @@ erts_ptr_id(void *ptr)
return ptr;
}
-#ifdef DEBUG
-/*
- * Handy functions when using a debugger - don't use in the code!
- */
-
-void upp(byte *buf, size_t sz)
-{
- bin_write(ERTS_PRINT_STDERR, NULL, buf, sz);
-}
-
-void pat(Eterm atom)
-{
- upp(atom_tab(atom_val(atom))->name,
- atom_tab(atom_val(atom))->len);
-}
-
-
-void pinfo()
-{
- process_info(ERTS_PRINT_STDOUT, NULL);
-}
-
-
-void pp(p)
-Process *p;
-{
- if(p)
- print_process_info(ERTS_PRINT_STDERR, NULL, p);
-}
-
-void ppi(Eterm pid)
-{
- pp(erts_proc_lookup(pid));
-}
-
-void td(Eterm x)
-{
- erts_fprintf(stderr, "%T\n", x);
-}
-
-void
-ps(Process* p, Eterm* stop)
-{
- Eterm* sp = STACK_START(p) - 1;
-
- if (stop <= STACK_END(p)) {
- stop = STACK_END(p) + 1;
- }
-
- while(sp >= stop) {
- erts_printf("%p: %.75T\n", sp, *sp);
- sp--;
- }
-}
-#endif