aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rwxr-xr-xerts/autoconf/configure.vxworks8
-rw-r--r--erts/configure.in2
-rw-r--r--erts/doc/src/notes.xml15
-rw-r--r--erts/emulator/beam/atom.names1
-rw-r--r--erts/emulator/beam/erl_bif_info.c8
-rw-r--r--erts/emulator/beam/erl_lock_check.c41
-rw-r--r--erts/emulator/beam/erl_port.h16
-rw-r--r--erts/emulator/beam/erl_proc_sig_queue.c26
-rw-r--r--erts/emulator/beam/erl_term.h48
-rw-r--r--erts/emulator/beam/erl_trace.c12
-rw-r--r--erts/emulator/beam/msg_instrs.tab3
-rw-r--r--erts/emulator/beam/utils.c162
-rw-r--r--erts/emulator/hipe/hipe_native_bif.c3
-rw-r--r--erts/emulator/nifs/win32/win_prim_file.c50
-rw-r--r--erts/emulator/test/dgawd_handler.erl4
-rw-r--r--erts/etc/common/heart.c5
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin54148 -> 54476 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin50572 -> 51452 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin27428 -> 27768 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl8
-rw-r--r--erts/preloaded/src/init.erl58
-rw-r--r--erts/preloaded/src/prim_file.erl9
-rw-r--r--erts/vsn.mk2
23 files changed, 323 insertions, 158 deletions
diff --git a/erts/autoconf/configure.vxworks b/erts/autoconf/configure.vxworks
index a13e0a6c56..18ca1718d6 100755
--- a/erts/autoconf/configure.vxworks
+++ b/erts/autoconf/configure.vxworks
@@ -68,10 +68,6 @@ WIND_BASE=${WIND_BASE:=`ypmatch tornado passwd | awk -F: '{print $6}'`/$VXTOP}
# These are created by autoconf.
MKDIRS="${ERL_TOP}/lib/os_mon/priv/bin/$target
${ERL_TOP}/lib/os_mon/priv/obj/$target
- ${ERL_TOP}/lib/orber/priv/obj/$target
- ${ERL_TOP}/lib/orber/priv/bin/$target
- ${ERL_TOP}/lib/ic/priv/lib/$target
- ${ERL_TOP}/lib/ic/priv/obj/$target
${ERL_TOP}/lib/asn1/priv/lib/$target
${ERL_TOP}/lib/asn1/priv/obj/$target
${ERL_TOP}/lib/erl_interface/obj/$target
@@ -100,8 +96,6 @@ etcdir=${ERL_TOP}/erts/etc/common
erlint_dir=${ERL_TOP}/lib/erl_interface/src
epmd_dir=${ERL_TOP}/erts/epmd/src
os_mon_dir=${ERL_TOP}/lib/os_mon/c_src
-orber_dir=${ERL_TOP}/lib/orber/c_src
-ic_dir=${ERL_TOP}/lib/ic/c_src
internal_tools_dir=${ERL_TOP}
libdir=${ERL_TOP}/lib
tsdir=$libdir/test_server/src
@@ -121,10 +115,8 @@ CONFIG_FILES="${ERL_TOP}/erts/emulator/$host/Makefile
$internal_tools_dir/make/$host/otp.mk
$os_mon_dir/$host/Makefile
$zlibdir/$host/Makefile
- $ic_dir/$host/Makefile
$runtime_tools_dir/$host/Makefile
$tools_dir/$host/Makefile
- $orber_dir/$host/Makefile"
for file in $CONFIG_FILES; do
new_name=`echo $file|sed "s%/$host/%/$target/%"`
diff --git a/erts/configure.in b/erts/configure.in
index 5d9dc9aa43..d1c5fe324b 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -4818,10 +4818,8 @@ dnl The ones below should be moved to their respective lib
dnl
dnl ../lib/ssl/c_src/$host/Makefile:../lib/ssl/c_src/Makefile.in
AC_CONFIG_FILES([
- ../lib/ic/c_src/$host/Makefile:../lib/ic/c_src/Makefile.in
../lib/os_mon/c_src/$host/Makefile:../lib/os_mon/c_src/Makefile.in
../lib/crypto/c_src/$host/Makefile:../lib/crypto/c_src/Makefile.in
- ../lib/orber/c_src/$host/Makefile:../lib/orber/c_src/Makefile.in
../lib/runtime_tools/c_src/$host/Makefile:../lib/runtime_tools/c_src/Makefile.in
../lib/tools/c_src/$host/Makefile:../lib/tools/c_src/Makefile.in
])
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index fcc7ec5b66..929d569f16 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -31,6 +31,21 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 9.3.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fixed a crash in <c>heart:get_cmd/0</c> when the
+ stored command was too long.</p>
+ <p>
+ Own Id: OTP-15034</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 9.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index cceca66850..fba0611042 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -358,6 +358,7 @@ atom loaded
atom load_cancelled
atom load_failure
atom local
+atom logger
atom long_gc
atom long_schedule
atom low
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 8687aefd78..6f9e507228 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -757,7 +757,7 @@ typedef struct {
static ErtsProcessInfoArgs pi_args[] = {
{am_registered_name, 0, 0, ERTS_PROC_LOCK_MAIN},
- {am_current_function, 4, 0, ERTS_PROC_LOCK_MAIN},
+ {am_current_function, 4, ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
{am_initial_call, 4, 0, ERTS_PROC_LOCK_MAIN},
{am_status, 0, 0, 0},
{am_messages, 0, ERTS_PI_FLAG_WANT_MSGS|ERTS_PI_FLAG_NEED_MSGQ_LEN|ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
@@ -779,15 +779,15 @@ static ErtsProcessInfoArgs pi_args[] = {
{am_binary, 0, ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
{am_sequential_trace_token, 0, 0, ERTS_PROC_LOCK_MAIN},
{am_catchlevel, 0, 0, ERTS_PROC_LOCK_MAIN},
- {am_backtrace, 0, 0, ERTS_PROC_LOCK_MAIN},
+ {am_backtrace, 0, ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
{am_last_calls, 0, 0, ERTS_PROC_LOCK_MAIN},
{am_total_heap_size, 0, ERTS_PI_FLAG_NEED_MSGQ_LEN|ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
{am_suspending, 0, ERTS_PI_FLAG_FORCE_SIG_SEND, 0},
{am_min_heap_size, 0, 0, ERTS_PROC_LOCK_MAIN},
{am_min_bin_vheap_size, 0, 0, ERTS_PROC_LOCK_MAIN},
{am_max_heap_size, 0, 0, ERTS_PROC_LOCK_MAIN},
- {am_current_location, 0, 0, ERTS_PROC_LOCK_MAIN},
- {am_current_stacktrace, 0, 0, ERTS_PROC_LOCK_MAIN},
+ {am_current_location, 0, ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
+ {am_current_stacktrace, 0, ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
{am_message_queue_data, 0, 0, ERTS_PROC_LOCK_MAIN},
{am_garbage_collection_info, ERTS_PROCESS_GC_INFO_MAX_SIZE, 0, ERTS_PROC_LOCK_MAIN},
{am_magic_ref, 0, ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c
index d66410367b..463ae898a3 100644
--- a/erts/emulator/beam/erl_lock_check.c
+++ b/erts/emulator/beam/erl_lock_check.c
@@ -217,6 +217,14 @@ typedef struct {
static lc_matrix_t tot_lc_matrix;
+#define ERTS_LC_FB_CHUNK_SIZE 10
+
+typedef struct lc_alloc_chunk_t_ lc_alloc_chunk_t;
+struct lc_alloc_chunk_t_ {
+ lc_alloc_chunk_t* next;
+ lc_free_block_t array[ERTS_LC_FB_CHUNK_SIZE];
+};
+
typedef struct lc_thread_t_ lc_thread_t;
struct lc_thread_t_ {
char *thread_name;
@@ -227,6 +235,7 @@ struct lc_thread_t_ {
lc_locked_lock_list_t locked;
lc_locked_lock_list_t required;
lc_free_block_t *free_blocks;
+ lc_alloc_chunk_t *chunks;
lc_matrix_t matrix;
};
@@ -235,14 +244,6 @@ static ethr_tsd_key locks_key;
static lc_thread_t *lc_threads = NULL;
static ethr_spinlock_t lc_threads_lock;
-
-#ifdef ERTS_LC_STATIC_ALLOC
-#define ERTS_LC_FB_CHUNK_SIZE 10000
-#else
-#define ERTS_LC_FB_CHUNK_SIZE 10
-#endif
-
-
static ERTS_INLINE void
lc_lock_threads(void)
{
@@ -268,12 +269,16 @@ static ERTS_INLINE void lc_free(lc_thread_t* thr, lc_locked_lock_t *p)
static lc_locked_lock_t *lc_core_alloc(lc_thread_t* thr)
{
int i;
- lc_free_block_t *fbs;
- fbs = (lc_free_block_t *) malloc(sizeof(lc_free_block_t)
- * ERTS_LC_FB_CHUNK_SIZE);
- if (!fbs) {
+ lc_alloc_chunk_t* chunk;
+ lc_free_block_t* fbs;
+ chunk = (lc_alloc_chunk_t*) malloc(sizeof(lc_alloc_chunk_t));
+ if (!chunk) {
ERTS_INTERNAL_ERROR("Lock checker failed to allocate memory!");
}
+ chunk->next = thr->chunks;
+ thr->chunks = chunk;
+
+ fbs = chunk->array;
for (i = 1; i < ERTS_LC_FB_CHUNK_SIZE - 1; i++) {
#ifdef DEBUG
sys_memset((void *) &fbs[i], 0xdf, sizeof(lc_free_block_t));
@@ -321,6 +326,7 @@ create_thread_data(char *thread_name)
thr->locked.last = NULL;
thr->prev = NULL;
thr->free_blocks = NULL;
+ thr->chunks = NULL;
sys_memzero(&thr->matrix, sizeof(thr->matrix));
lc_lock_threads();
@@ -336,7 +342,7 @@ create_thread_data(char *thread_name)
static void collect_matrix(lc_matrix_t*);
static void
-destroy_locked_locks(lc_thread_t *thr)
+destroy_thread_data(lc_thread_t *thr)
{
ASSERT(thr->thread_name);
free((void *) thr->thread_name);
@@ -359,8 +365,13 @@ destroy_locked_locks(lc_thread_t *thr)
lc_unlock_threads();
- free((void *) thr);
+ while (thr->chunks) {
+ lc_alloc_chunk_t* free_me = thr->chunks;
+ thr->chunks = thr->chunks->next;
+ free(free_me);
+ }
+ free((void *) thr);
}
static ERTS_INLINE lc_thread_t *
@@ -615,7 +626,7 @@ thread_exit_handler(void)
print_curr_locks(thr);
lc_abort();
}
- destroy_locked_locks(thr);
+ destroy_thread_data(thr);
/* erts_tsd_set(locks_key, NULL); */
}
}
diff --git a/erts/emulator/beam/erl_port.h b/erts/emulator/beam/erl_port.h
index 2a98a6f00b..9b52b648e5 100644
--- a/erts/emulator/beam/erl_port.h
+++ b/erts/emulator/beam/erl_port.h
@@ -485,6 +485,8 @@ ERTS_GLB_INLINE Uint32 erts_portid2status(Eterm);
ERTS_GLB_INLINE int erts_is_port_alive(Eterm);
ERTS_GLB_INLINE int erts_is_valid_tracer_port(Eterm);
ERTS_GLB_INLINE int erts_port_driver_callback_epilogue(Port *, erts_aint32_t *);
+ERTS_GLB_INLINE Port *erts_get_current_port(void);
+ERTS_GLB_INLINE Eterm erts_get_current_port_id(void);
#define erts_drvport2port(Prt) erts_drvport2port_state((Prt), NULL)
@@ -812,6 +814,20 @@ erts_port_driver_callback_epilogue(Port *prt, erts_aint32_t *statep)
return reds;
}
+ERTS_GLB_INLINE
+Port *erts_get_current_port(void)
+{
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
+ return esdp ? esdp->current_port : NULL;
+}
+
+ERTS_GLB_INLINE
+Eterm erts_get_current_port_id(void)
+{
+ Port *port = erts_get_current_port();
+ return port ? port->common.id : THE_NON_VALUE;
+}
+
#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
void erts_port_resume_procs(Port *);
diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c
index a2e6f1d39d..5165cd22a5 100644
--- a/erts/emulator/beam/erl_proc_sig_queue.c
+++ b/erts/emulator/beam/erl_proc_sig_queue.c
@@ -2558,18 +2558,6 @@ handle_process_info(Process *c_p, ErtsSigRecvTracing *tracing,
*c_p->sig_qs.last = NULL;
}
- if (!pisig->common.specific.next) {
- /*
- * No more signals in middle queue...
- *
- * Process-info 'status' needs sig-q
- * process flag to be updated in order
- * to show accurate result...
- */
- erts_atomic32_read_band_nob(&c_p->state,
- ~ERTS_PSFLG_SIG_Q);
- }
-
#ifdef ERTS_PROC_SIG_HARD_DEBUG_SIGQ_MSG_LEN
{
Sint len;
@@ -2583,8 +2571,20 @@ handle_process_info(Process *c_p, ErtsSigRecvTracing *tracing,
#endif
}
}
- if (is_alive)
+ if (is_alive) {
+ if (!pisig->common.specific.next) {
+ /*
+ * No more signals in middle queue...
+ *
+ * Process-info 'status' needs sig-q
+ * process flag to be updated in order
+ * to show accurate result...
+ */
+ erts_atomic32_read_band_nob(&c_p->state,
+ ~ERTS_PSFLG_SIG_Q);
+ }
remove_nm_sig(c_p, sig, next_nm_sig);
+ }
rp = erts_proc_lookup(pisig->requester);
ASSERT(c_p != rp);
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index 18483fca35..bddf403b0a 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -1184,6 +1184,54 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm)
#define is_map(x) (is_boxed((x)) && is_map_header(*boxed_val(x)))
#define is_not_map(x) (!is_map(x))
+#define MAP_HEADER(hp, sz, keys) \
+ ((hp)[0] = MAP_HEADER_FLATMAP, \
+ (hp)[1] = sz, \
+ (hp)[2] = keys)
+
+#define MAP_SZ(sz) (MAP_HEADER_FLATMAP_SZ + 2*sz + 1)
+
+#define MAP0_SZ MAP_SZ(0)
+#define MAP1_SZ MAP_SZ(1)
+#define MAP2_SZ MAP_SZ(2)
+#define MAP3_SZ MAP_SZ(3)
+#define MAP4_SZ MAP_SZ(4)
+#define MAP5_SZ MAP_SZ(5)
+#define MAP0(hp) \
+ (MAP_HEADER(hp, 0, TUPLE0(hp+MAP_HEADER_FLATMAP_SZ)), \
+ make_flatmap(hp))
+#define MAP1(hp, k1, v1) \
+ (MAP_HEADER(hp, 1, TUPLE1(hp+1+MAP_HEADER_FLATMAP_SZ, k1)), \
+ (hp)[MAP_HEADER_FLATMAP_SZ+0] = v1, \
+ make_flatmap(hp))
+#define MAP2(hp, k1, v1, k2, v2) \
+ (MAP_HEADER(hp, 2, TUPLE2(hp+2+MAP_HEADER_FLATMAP_SZ, k1, k2)), \
+ (hp)[MAP_HEADER_FLATMAP_SZ+0] = v1, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+1] = v2, \
+ make_flatmap(hp))
+#define MAP3(hp, k1, v1, k2, v2, k3, v3) \
+ (MAP_HEADER(hp, 3, TUPLE3(hp+3+MAP_HEADER_FLATMAP_SZ, k1, k2, k3)), \
+ (hp)[MAP_HEADER_FLATMAP_SZ+0] = v1, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+1] = v2, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+2] = v3, \
+ make_flatmap(hp))
+#define MAP4(hp, k1, v1, k2, v2, k3, v3, k4, v4) \
+ (MAP_HEADER(hp, 4, TUPLE4(hp+4+MAP_HEADER_FLATMAP_SZ, k1, k2, k3, k4)), \
+ (hp)[MAP_HEADER_FLATMAP_SZ+0] = v1, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+1] = v2, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+2] = v3, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+3] = v4, \
+ make_flatmap(hp))
+#define MAP5(hp, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5) \
+ (MAP_HEADER(hp, 5, TUPLE5(hp+5+MAP_HEADER_FLATMAP_SZ, k1, k2, k3, k4, k5)), \
+ (hp)[MAP_HEADER_FLATMAP_SZ+0] = v1, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+1] = v2, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+2] = v3, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+3] = v4, \
+ (hp)[MAP_HEADER_FLATMAP_SZ+4] = v5, \
+ make_flatmap(hp))
+
+
/* number tests */
#define is_integer(x) (is_small(x) || is_big(x))
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 1e833539b3..065a560b52 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -2044,7 +2044,7 @@ enqueue_sys_msg(enum ErtsSysMsgType type,
void
erts_queue_error_logger_message(Eterm from, Eterm msg, ErlHeapFragment *bp)
{
- enqueue_sys_msg(SYS_MSG_TYPE_ERRLGR, from, am_error_logger, msg, bp);
+ enqueue_sys_msg(SYS_MSG_TYPE_ERRLGR, from, am_logger, msg, bp);
}
void
@@ -2110,13 +2110,13 @@ sys_msg_disp_failure(ErtsSysMsgQ *smqp, Eterm receiver)
erts_thr_progress_unblock();
break;
case SYS_MSG_TYPE_ERRLGR: {
- char *no_elgger = "(no error logger present)";
+ char *no_elgger = "(no logger present)";
Eterm *tp;
Eterm tag;
if (is_not_tuple(smqp->msg)) {
unexpected_elmsg:
erts_fprintf(stderr,
- "%s unexpected error logger message: %T\n",
+ "%s unexpected logger message: %T\n",
no_elgger,
smqp->msg);
}
@@ -2284,7 +2284,7 @@ sys_msg_dispatcher_func(void *unused)
}
break;
case SYS_MSG_TYPE_ERRLGR:
- receiver = am_error_logger;
+ receiver = am_logger;
break;
default:
receiver = NIL;
@@ -2313,7 +2313,7 @@ sys_msg_dispatcher_func(void *unused)
erts_proc_unlock(proc, proc_locks);
}
}
- else if (receiver == am_error_logger) {
+ else if (receiver == am_logger) {
proc = erts_whereis_process(NULL,0,receiver,proc_locks,0);
if (!proc)
goto failure;
@@ -2379,7 +2379,7 @@ erts_foreach_sys_msg_in_q(void (*func)(Eterm,
to = erts_get_system_profile();
break;
case SYS_MSG_TYPE_ERRLGR:
- to = am_error_logger;
+ to = am_logger;
break;
default:
to = NIL;
diff --git a/erts/emulator/beam/msg_instrs.tab b/erts/emulator/beam/msg_instrs.tab
index 26bea0efc6..9bf3aefaca 100644
--- a/erts/emulator/beam/msg_instrs.tab
+++ b/erts/emulator/beam/msg_instrs.tab
@@ -102,6 +102,9 @@ i_loop_rec(Dest) {
if (ERTS_UNLIKELY(msgp == NULL)) {
int get_out;
SWAPOUT;
+ $SET_CP_I_ABS(I);
+ c_p->arity = 0;
+ c_p->current = NULL;
FCALLS -= erts_proc_sig_receive_helper(c_p, FCALLS, neg_o_reds,
&msgp, &get_out);
SWAPIN;
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 2e22130524..d74052d8b2 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -1924,145 +1924,155 @@ make_internal_hash(Eterm term, Uint32 salt)
#undef HCONST
#undef MIX
+/* error_logger !
+ {log, Level, format, [args], #{ gl, pid, time, error_logger => #{tag, emulator => true} }}
+*/
static Eterm
-do_allocate_logger_message(Eterm gleader, Eterm **hp, ErlOffHeap **ohp,
- ErlHeapFragment **bp, Process **p, Uint sz)
+do_allocate_logger_message(Eterm gleader, ErtsMonotonicTime *ts, Eterm *pid,
+ Eterm **hp, ErlOffHeap **ohp,
+ ErlHeapFragment **bp, Uint sz)
{
Uint gl_sz;
gl_sz = IS_CONST(gleader) ? 0 : size_object(gleader);
- sz = sz + gl_sz;
+ sz = sz + gl_sz + 6 /*outer 5-tuple*/
+ + MAP2_SZ /* error_logger map */;
+
+ *pid = erts_get_current_pid();
+
+ if (is_nil(gleader) && is_non_value(*pid)) {
+ sz += MAP2_SZ /* metadata map no gl, no pid */;
+ } else if (is_nil(gleader) || is_non_value(*pid))
+ sz += MAP3_SZ /* metadata map no gl or no pid*/;
+ else
+ sz += MAP4_SZ /* metadata map w gl w pid*/;
+
+ *ts = ERTS_MONOTONIC_TO_USEC(erts_get_monotonic_time(NULL)) + ERTS_MONOTONIC_OFFSET_USEC;
+ erts_bld_sint64(NULL, &sz, *ts);
*bp = new_message_buffer(sz);
*ohp = &(*bp)->off_heap;
*hp = (*bp)->mem;
- return (is_nil(gleader)
- ? am_noproc
- : (IS_CONST(gleader)
- ? gleader
- : copy_struct(gleader,gl_sz,hp,*ohp)));
+ return copy_struct(gleader,gl_sz,hp,*ohp);
}
-static void do_send_logger_message(Eterm *hp, ErlOffHeap *ohp, ErlHeapFragment *bp,
- Process *p, Eterm message)
+static void do_send_logger_message(Eterm gl, Eterm tag, Eterm format, Eterm args,
+ ErtsMonotonicTime ts, Eterm pid,
+ Eterm *hp, ErlHeapFragment *bp)
{
-#ifdef HARDDEBUG
- erts_fprintf(stderr, "%T\n", message);
-#endif
- {
- Eterm from = erts_get_current_pid();
- if (is_not_internal_pid(from))
- from = NIL;
- erts_queue_error_logger_message(from, message, bp);
+ Eterm message, md, el_tag = tag;
+ Eterm time = erts_bld_sint64(&hp, NULL, ts);
+
+ /* This mapping is needed for the backwards compatible error_logger */
+ switch (tag) {
+ case am_info: el_tag = am_info_msg; break;
+ case am_warning: el_tag = am_warning_msg; break;
+ default:
+ ASSERT(am_error);
+ break;
}
+
+ md = MAP2(hp, am_emulator, am_true,
+ am_atom_put("tag", 3), el_tag);
+ hp += MAP2_SZ;
+
+ if (is_nil(gl) && is_non_value(pid)) {
+ /* no gl and no pid, probably from a port */
+ md = MAP2(hp,
+ am_error_logger, md,
+ am_time, time);
+ hp += MAP2_SZ;
+ pid = NIL;
+ } else if (is_nil(gl)) {
+ /* no gl */
+ md = MAP3(hp,
+ am_error_logger, md,
+ am_pid, pid,
+ am_time, time);
+ hp += MAP3_SZ;
+ } else if (is_non_value(pid)) {
+ /* no gl */
+ md = MAP3(hp,
+ am_error_logger, md,
+ am_atom_put("gl", 2), gl,
+ am_time, time);
+ hp += MAP3_SZ;
+ pid = NIL;
+ } else {
+ md = MAP4(hp,
+ am_error_logger, md,
+ am_atom_put("gl", 2), gl,
+ am_pid, pid,
+ am_time, time);
+ hp += MAP4_SZ;
+ }
+
+ message = TUPLE5(hp, am_log, tag, format, args, md);
+ erts_queue_error_logger_message(pid, message, bp);
}
-/* error_logger !
- {notify,{info_msg,gleader,{emulator,format,[args]}}} |
- {notify,{error,gleader,{emulator,format,[args]}}} |
- {notify,{warning_msg,gleader,{emulator,format,[args}]}} */
-static int do_send_to_logger(Eterm tag, Eterm gleader, char *buf, size_t len)
+static int do_send_to_logger(Eterm tag, Eterm gl, char *buf, size_t len)
{
Uint sz;
- Eterm gl;
- Eterm list,args,format,tuple1,tuple2,tuple3;
+ Eterm list, args, format, pid;
+ ErtsMonotonicTime ts;
Eterm *hp = NULL;
ErlOffHeap *ohp = NULL;
ErlHeapFragment *bp = NULL;
- Process *p = NULL;
-
- ASSERT(is_atom(tag));
-
- if (len == 0) {
- return -1;
- }
sz = len * 2 /* message list */ + 2 /* cons surrounding message list */
- + 3 /*outer 2-tuple*/ + 4 /* middle 3-tuple */ + 4 /*inner 3-tuple */
+ 8 /* "~s~n" */;
/* gleader size is accounted and allocated next */
- gl = do_allocate_logger_message(gleader, &hp, &ohp, &bp, &p, sz);
-
- if(is_nil(gl)) {
- /* buf *always* points to a null terminated string */
- erts_fprintf(stderr, "(no error logger present) %T: \"%s\"\n",
- tag, buf);
- return 0;
- }
+ gl = do_allocate_logger_message(gl, &ts, &pid, &hp, &ohp, &bp, sz);
list = buf_to_intlist(&hp, buf, len, NIL);
args = CONS(hp,list,NIL);
hp += 2;
format = buf_to_intlist(&hp, "~s~n", 4, NIL);
- tuple1 = TUPLE3(hp, am_emulator, format, args);
- hp += 4;
- tuple2 = TUPLE3(hp, tag, gl, tuple1);
- hp += 4;
- tuple3 = TUPLE2(hp, am_notify, tuple2);
- do_send_logger_message(hp, ohp, bp, p, tuple3);
+ do_send_logger_message(gl, tag, format, args, ts, pid, hp, bp);
return 0;
}
-static int do_send_term_to_logger(Eterm tag, Eterm gleader,
+static int do_send_term_to_logger(Eterm tag, Eterm gl,
char *buf, size_t len, Eterm args)
{
Uint sz;
- Eterm gl;
Uint args_sz;
- Eterm format,tuple1,tuple2,tuple3;
+ Eterm format, pid;
+ ErtsMonotonicTime ts;
Eterm *hp = NULL;
ErlOffHeap *ohp = NULL;
ErlHeapFragment *bp = NULL;
- Process *p = NULL;
- ASSERT(is_atom(tag));
+ ASSERT(len > 0);
args_sz = size_object(args);
- sz = len * 2 /* format */ + args_sz
- + 3 /*outer 2-tuple*/ + 4 /* middle 3-tuple */ + 4 /*inner 3-tuple */;
+ sz = len * 2 /* format */ + args_sz;
/* gleader size is accounted and allocated next */
- gl = do_allocate_logger_message(gleader, &hp, &ohp, &bp, &p, sz);
-
- if(is_nil(gl)) {
- /* buf *always* points to a null terminated string */
- erts_fprintf(stderr, "(no error logger present) %T: \"%s\" %T\n",
- tag, buf, args);
- return 0;
- }
+ gl = do_allocate_logger_message(gl, &ts, &pid, &hp, &ohp, &bp, sz);
format = buf_to_intlist(&hp, buf, len, NIL);
args = copy_struct(args, args_sz, &hp, ohp);
- tuple1 = TUPLE3(hp, am_emulator, format, args);
- hp += 4;
- tuple2 = TUPLE3(hp, tag, gl, tuple1);
- hp += 4;
- tuple3 = TUPLE2(hp, am_notify, tuple2);
- do_send_logger_message(hp, ohp, bp, p, tuple3);
+ do_send_logger_message(gl, tag, format, args, ts, pid, hp, bp);
return 0;
}
static ERTS_INLINE int
send_info_to_logger(Eterm gleader, char *buf, size_t len)
{
- return do_send_to_logger(am_info_msg, gleader, buf, len);
+ return do_send_to_logger(am_info, gleader, buf, len);
}
static ERTS_INLINE int
send_warning_to_logger(Eterm gleader, char *buf, size_t len)
{
- Eterm tag;
- switch (erts_error_logger_warnings) {
- case am_info: tag = am_info_msg; break;
- case am_warning: tag = am_warning_msg; break;
- default: tag = am_error; break;
- }
- return do_send_to_logger(tag, gleader, buf, len);
+ return do_send_to_logger(erts_error_logger_warnings, gleader, buf, len);
}
static ERTS_INLINE int
diff --git a/erts/emulator/hipe/hipe_native_bif.c b/erts/emulator/hipe/hipe_native_bif.c
index cf8c4139be..24078af046 100644
--- a/erts/emulator/hipe/hipe_native_bif.c
+++ b/erts/emulator/hipe/hipe_native_bif.c
@@ -546,6 +546,9 @@ Eterm hipe_check_get_msg(Process *c_p)
if (!msgp) {
int get_out;
+ c_p->i = NULL;
+ c_p->arity = 0;
+ c_p->current = NULL;
(void) erts_proc_sig_receive_helper(c_p, CONTEXT_REDS, 0,
&msgp, &get_out);
/* FIXME: Need to bump reductions... */
diff --git a/erts/emulator/nifs/win32/win_prim_file.c b/erts/emulator/nifs/win32/win_prim_file.c
index 8058350b25..044bee62cf 100644
--- a/erts/emulator/nifs/win32/win_prim_file.c
+++ b/erts/emulator/nifs/win32/win_prim_file.c
@@ -24,6 +24,7 @@
#include "prim_file_nif.h"
+#include <winioctl.h>
#include <windows.h>
#include <strsafe.h>
#include <wchar.h>
@@ -671,11 +672,48 @@ static int is_executable_file(const efile_path_t *path) {
return 0;
}
+/* Returns whether the path refers to a link-like object, e.g. a junction
+ * point, symbolic link, or mounted folder. */
+static int is_name_surrogate(const efile_path_t *path) {
+ HANDLE handle;
+ int result;
+
+ handle = CreateFileW((const WCHAR*)path->data, GENERIC_READ,
+ FILE_SHARE_FLAGS, NULL, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT |
+ FILE_FLAG_BACKUP_SEMANTICS,
+ NULL);
+ result = 0;
+
+ if(handle != INVALID_HANDLE_VALUE) {
+ REPARSE_GUID_DATA_BUFFER reparse_buffer;
+ LPDWORD unused_length;
+ BOOL success;
+
+ success = DeviceIoControl(handle,
+ FSCTL_GET_REPARSE_POINT, NULL, 0,
+ &reparse_buffer, sizeof(reparse_buffer),
+ &unused_length, NULL);
+
+ /* ERROR_MORE_DATA is tolerated since we're guaranteed to have filled
+ * the field we want. */
+ if(success || GetLastError() == ERROR_MORE_DATA) {
+ result = IsReparseTagNameSurrogate(reparse_buffer.ReparseTag);
+ }
+
+ CloseHandle(handle);
+ }
+
+ return result;
+}
+
posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_fileinfo_t *result) {
BY_HANDLE_FILE_INFORMATION native_file_info;
DWORD attributes;
+ int is_link;
sys_memset(&native_file_info, 0, sizeof(native_file_info));
+ is_link = 0;
attributes = GetFileAttributesW((WCHAR*)path->data);
@@ -696,7 +734,11 @@ posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_
} else {
HANDLE handle;
- if(follow_links && (attributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
+ if(attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ is_link = is_name_surrogate(path);
+ }
+
+ if(follow_links && is_link) {
posix_errno_t posix_errno;
efile_path_t resolved_path;
@@ -737,7 +779,7 @@ posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_
}
}
- if(attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ if(is_link) {
result->type = EFILE_FILETYPE_SYMLINK;
/* This should be _S_IFLNK, but the old driver always set
* non-directories to _S_IFREG. */
@@ -917,6 +959,10 @@ posix_errno_t efile_read_link(ErlNifEnv *env, const efile_path_t *path, ERL_NIF_
return EINVAL;
}
+ if(!is_name_surrogate(path)) {
+ return EINVAL;
+ }
+
posix_errno = internal_read_link(path, &result_bin);
if(posix_errno == 0) {
diff --git a/erts/emulator/test/dgawd_handler.erl b/erts/emulator/test/dgawd_handler.erl
index 52cdd26427..29b9d6ac7b 100644
--- a/erts/emulator/test/dgawd_handler.erl
+++ b/erts/emulator/test/dgawd_handler.erl
@@ -42,10 +42,10 @@
%%====================================================================
install() ->
- gen_event:add_handler(error_logger, ?MODULE, []).
+ error_logger:add_report_handler(?MODULE, []).
restore() ->
- gen_event:delete_handler(error_logger, ?MODULE, []).
+ error_logger:delete_report_handler(?MODULE).
got_dgawd_report() ->
gen_event:call(error_logger, ?MODULE, got_dgawd_report, 10*60*1000).
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index bc353e384e..8f1e89b638 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -825,11 +825,8 @@ write_message(fd, mp)
int fd;
struct msg *mp;
{
- int len;
- char* tmp;
+ int len = ntohs(mp->len);
- tmp = (char*) &(mp->len);
- len = (*tmp * 256) + *(tmp+1);
if ((len == 0) || (len > MSG_BODY_SIZE)) {
return MSG_HDR_SIZE;
} /* cc68k wants (char *) */
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index e66343a5ad..10545086b5 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 6486ea750c..0473eda5fb 100644
--- a/erts/preloaded/ebin/init.beam
+++ b/erts/preloaded/ebin/init.beam
Binary files differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 4f11df2c38..d1b3f5dca4 100644
--- a/erts/preloaded/ebin/prim_file.beam
+++ b/erts/preloaded/ebin/prim_file.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index b82b9f5b46..42c1f32a8e 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -299,8 +299,12 @@ check_file_result(Func, Target, {error,Reason}) ->
end,
%% this is equal to calling error_logger:error_report/1 which
%% we don't want to do from code_server during system boot
- error_logger ! {notify,{error_report,group_leader(),
- {self(),std_error,Report}}},
+ logger ! {log,error,#{label=>{?MODULE,file_error},report=>Report},
+ #{pid=>self(),
+ gl=>group_leader(),
+ time=>erlang:monotonic_time(microsecond),
+ error_logger=>#{tag=>error_report,
+ type=>std_error}}},
error
end;
check_file_result(_, _, Other) ->
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index 0c74169e97..9e3de87e08 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -485,7 +485,12 @@ do_handle_msg(Msg,State) ->
X ->
case whereis(user) of
undefined ->
- catch error_logger ! {info, self(), {self(), X, []}};
+ Time = erlang:monotonic_time(microsecond),
+ catch logger ! {log, info, "init got unexpected: ~p", [X],
+ #{pid=>self(),
+ gl=>self(),
+ time=>Time,
+ error_logger=>#{tag=>info_msg}}};
User ->
User ! X,
ok
@@ -559,8 +564,11 @@ do_stop({stop,Status},State) ->
clear_system(BootPid,State) ->
Heart = get_heart(State#state.kernel),
- shutdown_pids(Heart,BootPid,State),
- unload(Heart).
+ Logger = get_logger(State#state.kernel),
+ shutdown_pids(Heart,Logger,BootPid,State),
+ unload(Heart),
+ kill_em([Logger]),
+ do_unload([logger_server]).
flush() ->
receive
@@ -580,19 +588,26 @@ stop_heart(State) ->
shutdown_kernel_pid(Pid, BootPid, self(), State)
end.
-shutdown_pids(Heart,BootPid,State) ->
+shutdown_pids(Heart,Logger,BootPid,State) ->
Timer = shutdown_timer(State#state.flags),
catch shutdown(State#state.kernel,BootPid,Timer,State),
- kill_all_pids(Heart), % Even the shutdown timer.
- kill_all_ports(Heart),
+ kill_all_pids(Heart,Logger), % Even the shutdown timer.
+ kill_all_ports(Heart), % Logger has no ports
flush_timout(Timer).
-get_heart([{heart,Pid}|_Kernel]) -> Pid;
-get_heart([_|Kernel]) -> get_heart(Kernel);
-get_heart(_) -> false.
+get_heart(Kernel) ->
+ get_kernelpid(heart,Kernel).
+get_logger(Kernel) ->
+ get_kernelpid(logger,Kernel).
-shutdown([{heart,_Pid}|Kernel],BootPid,Timer,State) ->
+get_kernelpid(Name,[{Name,Pid}|_Kernel]) -> Pid;
+get_kernelpid(Name,[_|Kernel]) -> get_kernelpid(Name,Kernel);
+get_kernelpid(_,_) -> false.
+
+
+shutdown([{Except,_Pid}|Kernel],BootPid,Timer,State)
+ when Except==heart; Except==logger ->
shutdown(Kernel, BootPid, Timer, State);
shutdown([{_Name,Pid}|Kernel],BootPid,Timer,State) ->
shutdown_kernel_pid(Pid, BootPid, Timer, State),
@@ -644,24 +659,25 @@ resend(_) ->
%%
%% Kill all existing pids in the system (except init and heart).
-kill_all_pids(Heart) ->
- case get_pids(Heart) of
+kill_all_pids(Heart,Logger) ->
+ case get_pids(Heart,Logger) of
[] ->
ok;
Pids ->
kill_em(Pids),
- kill_all_pids(Heart) % Continue until all are really killed.
+ kill_all_pids(Heart,Logger) % Continue until all are really killed.
end.
%% All except system processes.
-get_pids(Heart) ->
+get_pids(Heart,Logger) ->
Pids = [P || P <- processes(), not erts_internal:is_system_process(P)],
- delete(Heart,self(),Pids).
+ delete(Heart,Logger,self(),Pids).
-delete(Heart,Init,[Heart|Pids]) -> delete(Heart,Init,Pids);
-delete(Heart,Init,[Init|Pids]) -> delete(Heart,Init,Pids);
-delete(Heart,Init,[Pid|Pids]) -> [Pid|delete(Heart,Init,Pids)];
-delete(_,_,[]) -> [].
+delete(Heart,Logger,Init,[Heart|Pids]) -> delete(Heart,Logger,Init,Pids);
+delete(Heart,Logger,Init,[Logger|Pids]) -> delete(Heart,Logger,Init,Pids);
+delete(Heart,Logger,Init,[Init|Pids]) -> delete(Heart,Logger,Init,Pids);
+delete(Heart,Logger,Init,[Pid|Pids]) -> [Pid|delete(Heart,Logger,Init,Pids)];
+delete(_,_,_,[]) -> [].
kill_em([Pid|Pids]) ->
exit(Pid,kill),
@@ -691,9 +707,9 @@ kill_all_ports(_,_) ->
ok.
unload(false) ->
- do_unload(sub(erlang:pre_loaded(),erlang:loaded()));
+ do_unload(sub([logger_server|erlang:pre_loaded()],erlang:loaded()));
unload(_) ->
- do_unload(sub([heart|erlang:pre_loaded()],erlang:loaded())).
+ do_unload(sub([heart,logger_server|erlang:pre_loaded()],erlang:loaded())).
do_unload([M|Mods]) ->
catch erlang:purge_module(M),
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 432a8c15cd..558a0f883f 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.erl
@@ -557,8 +557,13 @@ list_dir_convert([RawName | Rest], SkipInvalid, Result) ->
{error, ignore} ->
list_dir_convert(Rest, SkipInvalid, Result);
{error, warning} ->
- error_logger:warning_msg(
- "Non-unicode filename ~p ignored\n", [RawName]),
+ %% this is equal to calling error_logger:warning_msg/2 which
+ %% we don't want to do from code_server during system boot
+ logger ! {log,warning,"Non-unicode filename ~p ignored\n", [RawName],
+ #{pid=>self(),
+ gl=>group_leader(),
+ time=>erlang:monotonic_time(microsecond),
+ error_logger=>#{tag=>warning_msg}}},
list_dir_convert(Rest, SkipInvalid, Result);
{error, _} ->
{error, {no_translation, RawName}}
diff --git a/erts/vsn.mk b/erts/vsn.mk
index c3a62a5535..25acd9cc34 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 9.3
+VSN = 9.3.1
# Port number 4365 in 4.2
# Port number 4366 in 4.3