diff options
Diffstat (limited to 'erts')
27 files changed, 415 insertions, 76 deletions
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4 index 2b47f7c4bc..ed492d55ff 100644 --- a/erts/aclocal.m4 +++ b/erts/aclocal.m4 @@ -1118,7 +1118,7 @@ case "$THR_LIB_NAME" in [Define if you have the "ose_spi/ose_spi.h" header file.])) ;; esac - if test "x$THR_LIB_NAME" == "xpthread"; then + if test "x$THR_LIB_NAME" = "xpthread"; then case $host_os in openbsd*) # The default stack size is insufficient for our needs @@ -1222,7 +1222,7 @@ case "$THR_LIB_NAME" in dnl dnl Check for functions dnl - if test "x$THR_LIB_NAME" == "xpthread"; then + if test "x$THR_LIB_NAME" = "xpthread"; then AC_CHECK_FUNC(pthread_spin_lock, \ [ethr_have_native_spinlock=yes \ AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \ diff --git a/erts/configure.in b/erts/configure.in index 9ebb56e3bc..04303da4f8 100644 --- a/erts/configure.in +++ b/erts/configure.in @@ -214,9 +214,6 @@ AC_ARG_ENABLE(native-libs, AS_HELP_STRING([--enable-native-libs], [compile Erlang libraries to native code])) -AC_ARG_ENABLE(tsp, -AS_HELP_STRING([--enable-tsp], [compile tsp app])) - AC_ARG_ENABLE(fp-exceptions, AS_HELP_STRING([--enable-fp-exceptions], [use hardware floating point exceptions (default if hipe enabled)]), @@ -366,6 +363,11 @@ AC_DEFINE_UNQUOTED(ASSUMED_CACHE_LINE_SIZE, $with_assumed_cache_line_size, [Assumed cache-line size (in bytes)]) +AC_ARG_ENABLE(systemd, +AS_HELP_STRING([--enable-systemd], [enable systemd support in epmd]), +[], +[enable_systemd=no]) + dnl Magic test for clearcase. OTP_RELEASE= if test "${ERLANG_COMMERCIAL_BUILD}" != ""; then @@ -456,10 +458,10 @@ AS_HELP_STRING([--enable-static-drivers], [comma seperated list of linked-in dri AC_SUBST(STATIC_DRIVERS) AC_ARG_WITH(ets-write-concurrency-locks, - AS_HELP_STRING([--with-ets-write-concurrency-locks={8,16,32,64,128,256}], - [specify how many locks the write_concurrency option for ets should use.]) - AS_HELP_STRING([--without-ets-write-concurrency-locks], - [use the default number of write_concurrency locks (default)])) +AS_HELP_STRING([--with-ets-write-concurrency-locks={8|16|32|64|128|256}], + [specify how many locks the write_concurrency option for ets should use.]) +AS_HELP_STRING([--without-ets-write-concurrency-locks], + [use the default number of write_concurrency locks (default)])) if test X"$with_ets_write_concurrency_locks" != X""; then AC_DEFINE_UNQUOTED(ERTS_DB_HASH_LOCK_CNT,$with_ets_write_concurrency_locks, @@ -1042,8 +1044,6 @@ AC_CHECK_LIB(dl, dlopen) AC_CHECK_LIB(inet, main) AC_CHECK_LIB(util, openpty) -AC_CHECK_LIB(systemd-daemon, sd_listen_fds) - dnl Try to find a thread library. dnl dnl ETHR_LIB_NAME, ETHR_LIBS, ETHR_X_LIBS, ETHR_THR_LIB_BASE and ETHR_DEFS @@ -1679,7 +1679,29 @@ AC_CHECK_MEMBERS([struct ifreq.ifr_enaddr], [], [], #endif ]) -AC_CHECK_HEADERS(systemd/sd-daemon.h) +dnl ---------------------------------------------------------------------- +dnl Check the availability of systemd +dnl ---------------------------------------------------------------------- +if test x"$enable_systemd" != x"no"; then + +systemd_daemon_save_LIBS=$LIBS +LIBS= +AC_SEARCH_LIBS(sd_listen_fds,[systemd systemd-daemon], + [have_sd_listen_fds=yes],[have_sd_listen_fds=no],$systemd_daemon_save_LIBS) +AC_CHECK_HEADERS(systemd/sd-daemon.h, + [have_systemd_sd_daemon_h=yes],[have_systemd_sd_daemon_h=no]) + +if test x"$have_sd_listen_fds" = x"yes" && \ + test x"$have_systemd_sd_daemon_h" = x"yes"; then + AC_DEFINE([HAVE_SYSTEMD_DAEMON],[1],[Define if you have systemd daemon]) + SYSTEMD_DAEMON_LIBS=$LIBS +elif test x"$enable_systemd" = x"yes"; then + AC_MSG_FAILURE([--enable-systemd was given, but test for systemd failed]) +fi +LIBS=$systemd_daemon_save_LIBS +fi +AC_SUBST(SYSTEMD_DAEMON_LIBS) + dnl ---------------------------------------------------------------------- dnl Check the availability for libdlpi @@ -3432,16 +3454,6 @@ dnl (using the --disable, --enable and --with switches). dnl ---------------------------------------------------------------------- # -# Check if we should compile TSP app -# - -TSP_APP= -if test X${enable_tsp} = Xyes; then - TSP_APP=tsp -fi -AC_SUBST(TSP_APP) - -# # Check if we should enable HiPE. # diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 9724a1345a..f8f4d14436 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -495,7 +495,7 @@ <c><![CDATA[werl]]></c>, not <c><![CDATA[erl]]></c> (<c><![CDATA[oldshell]]></c>). Note also that <c><![CDATA[Ctrl-Break]]></c> is used instead of <c><![CDATA[Ctrl-C]]></c> on Windows.</p> </item> - <tag><c><![CDATA[+c]]></c></tag> + <tag><marker id="+c"><c><![CDATA[+c]]></c></marker></tag> <item> <p>Disable compensation for sudden changes of system time.</p> <p>Normally, <c><![CDATA[erlang:now/0]]></c> will not immediately reflect @@ -510,6 +510,9 @@ reflect the current system time. Note that timers are based on <c><![CDATA[erlang:now/0]]></c>. If the system time jumps, timers then time out at the wrong time.</p> + <p><em>NOTE</em>: You can check whether the adjustment is enabled or + disabled by calling + <seealso marker="erlang#system_info_tolerant_timeofday">erlang:system_info(tolerant_timeofday)</seealso>.</p> </item> <tag><c><![CDATA[+d]]></c></tag> <item> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index e7e9b218f2..9ad42374bf 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -4842,6 +4842,8 @@ true</pre> <c><anno>Node</anno></c> does not exist, a useless pid is returned. Otherwise works like <seealso marker="#spawn_opt/4">spawn_opt/4</seealso>.</p> + <note><p>The <c>monitor</c> option is currently not supported by + <c>spawn_opt/5</c>.</p></note> </desc> </func> <func> @@ -6293,6 +6295,13 @@ ok (<seealso marker="erts:erl_driver#driver_async">driver_async()</seealso>) as an integer.</p> </item> + <tag><marker id="system_info_tolerant_timeofday"><c>tolerant_timeofday</c></marker></tag> + <item> + <p>Returns whether compensation for sudden changes of system + time is <c>enabled</c> or <c>disabled</c>.</p> + <p>See also <seealso marker="erts:erl#+c">+c</seealso> + command line flag.</p> + </item> <tag><c>trace_control_word</c></tag> <item> <p>Returns the value of the node's trace control word. diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 06a1230ca0..fcbeb6cf5c 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -1886,8 +1886,13 @@ do_send(Process *p, Eterm to, Eterm msg, int suspend, Eterm *refp) { Eterm id = erts_whereis_name_to_id(p, to); rp = erts_proc_lookup(id); - if (rp) + if (rp) { + if (IS_TRACED(p)) + trace_send(p, to, msg); + if (ERTS_PROC_GET_SAVED_CALLS_BUF(p)) + save_calls(p, &exp_send); goto send_message; + } pt = erts_port_lookup(id, (erts_port_synchronous_ops diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 9816883c9a..011e49f1fe 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -156,6 +156,7 @@ bif erts_internal:port_connect/2 bif erts_internal:request_system_task/3 bif erts_internal:check_process_code/2 +bif erts_internal:map_to_tuple_keys/1 # inet_db support bif erlang:port_set_data/2 diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 2adba9b240..4d5e55aaf5 100755 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -2691,6 +2691,11 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) else if (ERTS_IS_ATOM_STR("ets_limit",BIF_ARG_1)) { BIF_RET(make_small(erts_db_get_max_tabs())); } + else if (ERTS_IS_ATOM_STR("tolerant_timeofday",BIF_ARG_1)) { + BIF_RET(erts_disable_tolerant_timeofday + ? am_disabled + : am_enabled); + } BIF_ERROR(BIF_P, BADARG); } diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c index a5d67571e2..8f246ffa07 100644 --- a/erts/emulator/beam/erl_db.c +++ b/erts/emulator/beam/erl_db.c @@ -259,10 +259,11 @@ static void schedule_free_dbtable(DbTable* tb) /* * NON-SMP case: Caller is *not* allowed to access the *tb * structure after this function has returned! - * SMP case: Caller is allowed to access the *tb structure - * until the bif has returned (we typically - * need to unlock the table lock after this - * function has returned). + * SMP case: Caller is allowed to access the *common* part of the *tb + * structure until the bif has returned (we typically need to + * unlock the table lock after this function has returned). + * Caller is *not* allowed to access the specialized part + * (hash or tree) of *tb after this function has returned. */ ASSERT(erts_refc_read(&tb->common.ref, 0) == 0); erts_schedule_thr_prgr_later_cleanup_op(free_dbtable, @@ -3279,34 +3280,37 @@ erts_db_process_exiting(Process *c_p, ErtsProcLocks c_p_locks) } erts_smp_rwmtx_runlock(mmtl); if (tb) { - int reds; - DbFixation** pp; + int reds = 0; db_lock(tb, LCK_WRITE_REC); - #ifdef ERTS_SMP - erts_smp_mtx_lock(&tb->common.fixlock); - #endif - reds = 10; - - for (pp = &tb->common.fixations; *pp != NULL; - pp = &(*pp)->next) { - if ((*pp)->pid == pid) { - DbFixation* fix = *pp; - erts_aint_t diff = -((erts_aint_t) fix->counter); - erts_refc_add(&tb->common.ref,diff,0); - *pp = fix->next; - erts_db_free(ERTS_ALC_T_DB_FIXATION, - tb, fix, sizeof(DbFixation)); - ERTS_ETS_MISC_MEM_ADD(-sizeof(DbFixation)); - break; + if (!(tb->common.status & DB_DELETE)) { + DbFixation** pp; + + #ifdef ERTS_SMP + erts_smp_mtx_lock(&tb->common.fixlock); + #endif + reds = 10; + + for (pp = &tb->common.fixations; *pp != NULL; + pp = &(*pp)->next) { + if ((*pp)->pid == pid) { + DbFixation* fix = *pp; + erts_aint_t diff = -((erts_aint_t) fix->counter); + erts_refc_add(&tb->common.ref,diff,0); + *pp = fix->next; + erts_db_free(ERTS_ALC_T_DB_FIXATION, + tb, fix, sizeof(DbFixation)); + ERTS_ETS_MISC_MEM_ADD(-sizeof(DbFixation)); + break; + } + } + #ifdef ERTS_SMP + erts_smp_mtx_unlock(&tb->common.fixlock); + #endif + if (!IS_FIXED(tb) && IS_HASH_TABLE(tb->common.status)) { + db_unfix_table_hash(&(tb->hash)); + reds += 40; } - } - #ifdef ERTS_SMP - erts_smp_mtx_unlock(&tb->common.fixlock); - #endif - if (!IS_FIXED(tb) && IS_HASH_TABLE(tb->common.status)) { - db_unfix_table_hash(&(tb->hash)); - reds += 40; } db_unlock(tb, LCK_WRITE_REC); BUMP_REDS(c_p, reds); diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index 3ecb379326..5ced8c5ca0 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -198,7 +198,7 @@ typedef long long ErlDrvSInt64; #error No 64-bit integer type #endif -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(_WIN32) typedef ErlDrvUInt ErlDrvSizeT; typedef ErlDrvSInt ErlDrvSSizeT; #else diff --git a/erts/emulator/beam/erl_lock_check.c b/erts/emulator/beam/erl_lock_check.c index 7e3a90779d..c13eb87012 100644 --- a/erts/emulator/beam/erl_lock_check.c +++ b/erts/emulator/beam/erl_lock_check.c @@ -270,9 +270,9 @@ union erts_lc_free_block_t_ { static ethr_tsd_key locks_key; -static erts_lc_locked_locks_t *erts_locked_locks; +static erts_lc_locked_locks_t *erts_locked_locks = NULL; -static erts_lc_free_block_t *free_blocks; +static erts_lc_free_block_t *free_blocks = NULL; #ifdef ERTS_LC_STATIC_ALLOC #define ERTS_LC_FB_CHUNK_SIZE 10000 diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index fdd2d0c0f6..5e740aacdd 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -58,6 +58,8 @@ * - maps:size/1 * - maps:without/2 * + * DEBUG: for sharing calculation + * - erts_internal:map_to_tuple_keys/1 */ /* erlang:map_size/1 @@ -819,3 +821,17 @@ int erts_validate_and_sort_map(map_t* mp) } return 1; } + +/* + * erts_internal:map_to_tuple_keys/1 + * + * Used in erts_debug:size/1 + */ + +BIF_RETTYPE erts_internal_map_to_tuple_keys_1(BIF_ALIST_1) { + if (is_map(BIF_ARG_1)) { + map_t *mp = (map_t*)map_val(BIF_ARG_1); + BIF_RET(mp->keys); + } + BIF_ERROR(BIF_P, BADARG); +} diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index b4b97d7df1..b73f9b7f92 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -2672,6 +2672,13 @@ aux_thread(void *unused) ErtsThrPrgrCallbacks callbacks; int thr_prgr_active = 1; +#ifdef ERTS_ENABLE_LOCK_CHECK + { + char buf[] = "aux_thread"; + erts_lc_set_thread_name(buf); + } +#endif + ssi->event = erts_tse_fetch(); callbacks.arg = (void *) ssi; @@ -6144,7 +6151,7 @@ suspend_process(Process *c_p, Process *p) if (c_p == p) { state = erts_smp_atomic32_read_bor_relb(&p->state, ERTS_PSFLG_SUSPENDED); - ASSERT(state & ERTS_PSFLG_RUNNING); + ASSERT(state & (ERTS_PSFLG_RUNNING|ERTS_PSFLG_RUNNING_SYS)); suspended = (state & ERTS_PSFLG_SUSPENDED) ? -1: 1; } else { diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index 42f41c5f3d..878beb055b 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -360,7 +360,12 @@ efile_openfile(Efile_error* errInfo, /* Where to return error codes. */ int fd; int mode; /* Open mode. */ - if (stat(name, &statbuf) >= 0 && !ISREG(statbuf)) { + if (stat(name, &statbuf) < 0) { + /* statbuf is undefined: if the caller depends on it, + i.e. invoke_read_file(), fail the call immediately */ + if (pSize && flags == EFILE_MODE_READ) + return check_error(-1, errInfo); + } else if (!ISREG(statbuf)) { /* * For UNIX only, here is some ugly code to allow * /dev/null to be opened as a file. diff --git a/erts/emulator/test/erts_debug_SUITE.erl b/erts/emulator/test/erts_debug_SUITE.erl index 87778dd0c2..e5c904cfb9 100644 --- a/erts/emulator/test/erts_debug_SUITE.erl +++ b/erts/emulator/test/erts_debug_SUITE.erl @@ -67,6 +67,9 @@ test_size(Config) when is_list(Config) -> 2 = do_test_size({[]}), 3 = do_test_size({a,b}), 7 = do_test_size({a,[b,c]}), + 8 = do_test_size(#{b => 2,c => 3}), + 4 = do_test_size(#{}), + 32 = do_test_size(#{b => 2,c => 3,txt => "hello world"}), %% Test internal consistency of sizes, but without testing %% exact sizes. @@ -97,6 +100,9 @@ test_size(Config) when is_list(Config) -> do_test_size({SimplestFun,SimplestFun}, 2*FunSz0+do_test_size({a,b}), FunSz0+do_test_size({a,b})), + + M = id(#{ "atom" => first, i => 0}), + do_test_size([M,M#{ "atom" := other },M#{i := 42}],54,32), ok. do_test_size(Term) -> diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl index 8038888796..fdce157abc 100644 --- a/erts/emulator/test/match_spec_SUITE.erl +++ b/erts/emulator/test/match_spec_SUITE.erl @@ -1009,12 +1009,14 @@ loop_runner(Collector, Fun, Laps) -> end, loop_runner_cont(Collector, Fun, 0, Laps). -loop_runner_cont(_Collector, _Fun, Laps, Laps) -> +loop_runner_cont(Collector, _Fun, Laps, Laps) -> receive - {done, Collector} -> - io:format("loop_runner ~p exit after ~p laps\n", [self(), Laps]), - Collector ! {gone, self()} - end; + {done, Collector} -> ok; + {abort, Collector} -> ok + end, + io:format("loop_runner ~p exit after ~p laps\n", [self(), Laps]), + Collector ! {gone, self()}; + loop_runner_cont(Collector, Fun, N, Laps) -> Fun(), receive diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index ceb4afb5cf..f959714be7 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -155,6 +155,7 @@ misc_smoke_tests(Config) when is_list(Config) -> ?line true = is_binary(erlang:system_info(loaded)), ?line true = is_binary(erlang:system_info(dist)), ?line ok = try erlang:system_info({cpu_topology,erts_get_cpu_topology_error_case}), fail catch error:badarg -> ok end, + true = lists:member(erlang:system_info(tolerant_timeofday), [enabled, disabled]), ?line ok. diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl index 2251575e5a..4d7598cf1f 100644 --- a/erts/emulator/test/trace_SUITE.erl +++ b/erts/emulator/test/trace_SUITE.erl @@ -181,6 +181,13 @@ send_trace(Config) when is_list(Config) -> ?line {trace, Sender, send, to_receiver, Receiver} = receive_first(), ?line receive_nothing(), + %% Check that a message sent to another registered process is traced. + register(?MODULE,Receiver), + Sender ! {send_please, ?MODULE, to_receiver}, + {trace, Sender, send, to_receiver, ?MODULE} = receive_first(), + receive_nothing(), + unregister(?MODULE), + %% Check that a message sent to this process is traced. ?line Sender ! {send_please, self(), to_myself}, ?line receive to_myself -> ok end, @@ -188,6 +195,21 @@ send_trace(Config) when is_list(Config) -> ?line {trace, Sender, send, to_myself, Self} = receive_first(), ?line receive_nothing(), + %% Check that a message sent to dead process is traced. + {Pid,Ref} = spawn_monitor(fun() -> ok end), + receive {'DOWN',Ref,_,_,_} -> ok end, + Sender ! {send_please, Pid, to_dead}, + {trace, Sender, send_to_non_existing_process, to_dead, Pid} = receive_first(), + receive_nothing(), + + %% Check that a message sent to unknown registrated process is traced. + BadargSender = fun_spawn(fun sender/0), + 1 = erlang:trace(BadargSender, true, [send]), + unlink(BadargSender), + BadargSender ! {send_please, not_registered, to_unknown}, + {trace, BadargSender, send, to_unknown, not_registered} = receive_first(), + receive_nothing(), + %% Another process should not be able to trace Sender. ?line Intruder = fun_spawn(fun() -> erlang:trace(Sender, true, [send]) end), ?line {'EXIT', Intruder, {badarg, _}} = receive_first(), diff --git a/erts/emulator/utils/gen_git_version b/erts/emulator/utils/gen_git_version index ef06a4b8e2..9faf015b62 100755 --- a/erts/emulator/utils/gen_git_version +++ b/erts/emulator/utils/gen_git_version @@ -5,9 +5,9 @@ OUTPUT_FILE=$1 if command -v git 2>&1 >/dev/null && test -d $ERL_TOP/.git -o -f $ERL_TOP/.git then - VSN=`git describe --match "OTP_R[0-9][0-9][A-B]*" HEAD` + VSN=`git describe --match "OTP-[0-9]*" HEAD` case "$VSN" in - OTP_R*-g*) + OTP-*-g*) VSN=`echo $VSN | sed -e 's/.*-g\\(.*\\)/\\1/g'` ;; *) VSN="na" ;; esac @@ -36,4 +36,4 @@ then fi exit 0 fi -exit 1
\ No newline at end of file +exit 1 diff --git a/erts/epmd/src/Makefile.in b/erts/epmd/src/Makefile.in index 8dc8dae5f6..0c7787a3b1 100644 --- a/erts/epmd/src/Makefile.in +++ b/erts/epmd/src/Makefile.in @@ -84,7 +84,7 @@ LD = @LD@ ifeq ($(findstring ose,$(TARGET)),ose) LIBS = $(ERTS_INTERNAL_LIBS) @LIBS@ else -LIBS = @LIBS@ $(ERTS_INTERNAL_LIBS) +LIBS = @LIBS@ @SYSTEMD_DAEMON_LIBS@ $(ERTS_INTERNAL_LIBS) endif LDFLAGS = @LDFLAGS@ diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c index 93982c2f60..48fd7a5f9c 100644 --- a/erts/epmd/src/epmd_srv.c +++ b/erts/epmd/src/epmd_srv.c @@ -213,7 +213,7 @@ void run(EpmdVars *g) node_init(g); g->conn = conn_init(g); -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON if (g->is_systemd) { int n; @@ -310,7 +310,7 @@ void run(EpmdVars *g) SET_ADDR(iserv_addr[0],EPMD_ADDR_ANY,sport); num_sockets = 1; } -#ifdef HAVE_SYSTEMD_SD_DAEMON_H +#ifdef HAVE_SYSTEMD_DAEMON } #endif diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index 9e39764195..19c92681d0 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2005-2012. All Rights Reserved. +# Copyright Ericsson AB 2005-2014. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -54,13 +54,23 @@ document etp-help % etp-mfa, etp-cp, % etp-msgq, etpf-msgq, % etp-stacktrace, etp-stackdump, etpf-stackdump, etp-dictdump -% etp-offheapdump, etpf-offheapdump, -% etp-print-procs, etp-search-heaps, etp-search-alloc, +% etp-process-info, etp-process-memory-info +% etp-port-info, etp-port-state, etp-port-sched-flags +% etp-heapdump, etp-offheapdump, etpf-offheapdump, +% etp-search-heaps, etp-search-alloc, % etp-ets-tables, etp-ets-tabledump % % Complex commands that use the Erlang support module. % etp-overlapped-heaps, etp-chart, etp-chart-start, etp-chart-end -% +% +% System inspection +% etp-system-info, etp-schedulers, etp-process, etp-ports, etp-lc-dump, +% etp-migration-info, etp-processes-memory, +% etp-compile-info, etp-config-h-info +% +% Platform specific (when gdb fails you) +% etp-ppc-stacktrace +% % Erlang support module handling commands: % etp-run % @@ -1055,7 +1065,9 @@ define etp-cp-1 set $etp_cp_mid = $etp_cp_low + ($etp_cp_high-$etp_cp_low)/2 end if $etp_cp_p - set $etp_cp_low = (Eterm**)($etp_cp_p->start + 8) + # 12 = MI_FUNCTIONS + set $etp_cp_low = (Eterm**)($etp_cp_p->start + 12) + # 0 = MI_NUM_FUNCTIONS set $etp_cp_high = $etp_cp_low +$etp_cp_p->start[0] set $etp_cp_p = 0 while $etp_cp_low < $etp_cp_high @@ -3133,6 +3145,77 @@ document etp-ets-tabledump %--------------------------------------------------------------------------- end +define etp-lc-dump +# Non-reentrant + set $etp_lc_dump_thread = erts_locked_locks + while $etp_lc_dump_thread + printf "Thread %s\n", $etp_lc_dump_thread->thread_name + set $etp_lc_dump_thread_locked = $etp_lc_dump_thread->locked.first + while $etp_lc_dump_thread_locked + if 0 <= $etp_lc_dump_thread_locked->id && $etp_lc_dump_thread_locked->id < sizeof(erts_lock_order)/sizeof(erts_lc_lock_order_t) + printf " %s:", erts_lock_order[$etp_lc_dump_thread_locked->id].name + else + printf " unkown:" + end + if ($etp_lc_dump_thread_locked->extra & 0x3) == 0x3 + etp-1 $etp_lc_dump_thread_locked->extra + else + printf "%p", $etp_lc_dump_thread_locked->extra + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 0) + printf "[spinlock]" + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 1) + printf "[rw(spin)lock]" + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 2) + printf "[mutex]" + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 3) + printf "[rwmutex]" + end + if ($etp_lc_dump_thread_locked->flags & (0x1f)) == (1 << 4) + printf "[proclock]" + end + printf "(%s:%d)", $etp_lc_dump_thread_locked->file, $etp_lc_dump_thread_locked->line + if ($etp_lc_dump_thread_locked->flags & (0x60)) == (1 << 5) + printf "(r)" + end + if ($etp_lc_dump_thread_locked->flags & (0x60)) == ((1 << 5) | (1 << 6)) + printf "(rw)" + end + printf "\n" + set $etp_lc_dump_thread_locked = $etp_lc_dump_thread_locked->next + end + set $etp_lc_dump_thread = $etp_lc_dump_thread->next + end +end + +document etp-lc-dump +%--------------------------------------------------------------------------- +% etp-lc-dump +% +% Dump all info about locks in the lock checker +%--------------------------------------------------------------------------- +end + +define etp-ppc-stacktrace +# Args: R1 +# Non-reentrant + set $etp_ppc_st_fp = ($arg0) + while $etp_ppc_st_fp + info symbol ((void**)$etp_ppc_st_fp)[1] + set $etp_ppc_st_fp = ((void**)$etp_ppc_st_fp)[0] + end +end + +document etp-ppc-stacktrace +%--------------------------------------------------------------------------- +% etp-ppc-stacktrace R1 +% +% Dump stacktrace from given $r1 frame pointer +%--------------------------------------------------------------------------- +end ############################################################################ # OSE support @@ -3177,6 +3260,154 @@ define etp-thr end ############################################################################ +# erl_alloc_util (blocks and carriers) +# + +define etp-block-size-1 +# +# In: (Block_t*) in $arg0 +# Out: Byte size in $etp_blk_sz +# + if ($arg0)->bhdr & 1 + # Free block + set $etp_blk_sz = ($arg0)->bhdr & ~7 + else + # Allocated block + if !$etp_MBC_ABLK_SZ_MASK + if etp_arch_bits == 64 + set $etp_MBC_ABLK_OFFSET_SHIFT = (64 - 24) + else + set $etp_MBC_ABLK_OFFSET_SHIFT = (32 - 9) + end + set $etp_MBC_ABLK_SZ_MASK = ((UWord)1 << $etp_MBC_ABLK_OFFSET_SHIFT) - 1 - 7 + end + set $etp_blk_sz = ($arg0)->bhdr & $etp_MBC_ABLK_SZ_MASK + end +end + +define etp-block2mbc-1 +# +# In: (Block_t*) in $arg0 +# Out: (Carrier_t*) in $etp-mbc +# + if (($arg0)->bhdr) & 1 + # Free block + set $etp_mbc = ($arg0)->u.carrier + else + # Allocated block + if !$etp_MBC_ABLK_OFFSET_SHIFT + if etp_arch_bits == 64 + set $etp_MBC_ABLK_OFFSET_SHIFT = (64 - 24) + else + set $etp_MBC_ABLK_OFFSET_SHIFT = (32 - 9) + end + end + set $etp_mbc = (Carrier_t*) ((((UWord)($arg0) >> 18) - (($arg0)->bhdr >> $etp_MBC_ABLK_OFFSET_SHIFT)) << 18) + end +end + +define etp-block2mbc + etp-block2mbc-1 ((Block_t*)$arg0) + print $etp_mbc +end + +document etp-block2mbc +%--------------------------------------------------------------------------- +% Print pointer to multiblock carrier containing the argument (Block_t*) +%--------------------------------------------------------------------------- +end + +define etp-block + etp-block-size-1 ((Block_t*)$arg0) + if ((Block_t*)$arg0)->bhdr & 1 + printf "%#lx: FREE sz=%#x\n", ($arg0), $etp_blk_sz + else + printf "%#lx: ALLOCATED sz=%#x\n", ($arg0), $etp_blk_sz + end +end + +document etp-block +%--------------------------------------------------------------------------- +% Print memory block (Block_t*) +%--------------------------------------------------------------------------- +end + +define etp-carrier-blocks + set $etp_crr = (Carrier_t*) $arg0 + set $etp_alc = (Allctr_t*)($etp_crr->allctr.counter & ~7) + set $etp_blk = (Block_t*) ((char*)$etp_crr + $etp_alc->mbc_header_size) + set $etp_prev_blk = 0 + set $etp_error_cnt = 0 + set $etp_ablk_cnt = 0 + set $etp_fblk_cnt = 0 + + if $argc == 2 + set $etp_be_silent = $arg1 + else + set $etp_be_silent = 0 + end + + while 1 + if !$etp_be_silent + etp-block $etp_blk + else + etp-block-size-1 $etp_blk + end + etp-block2mbc-1 $etp_blk + if $etp_mbc != $etp_crr + printf "ERROR: Invalid carrier pointer %#lx in block at %#lx\n", $etp_mbc, $etp_blk + set $etp_error_cnt = $etp_error_cnt + 1 + end + if $etp_prev_blk + if ($etp_prev_blk->bhdr & 1) + # Prev is FREE + if ($etp_blk->bhdr & 1) + printf "ERROR: Adjacent FREE blocks at %#lx and %#lx\n", $etp_prev_blk, $etp_blk + set $etp_error_cnt = $etp_error_cnt + 1 + end + if !($etp_blk->bhdr & 2) + printf "ERROR: Missing PREV_FREE_BLK_HDR_FLG (2) in block at %#lx\n", $etp_blk + set $etp_error_cnt = $etp_error_cnt + 1 + end + end + end + if $etp_blk->bhdr & 1 + set $etp_fblk_cnt = $etp_fblk_cnt + 1 + else + set $etp_ablk_cnt = $etp_ablk_cnt + 1 + end + if $etp_blk->bhdr & 4 + # Last block + loop_break + end + # All free blocks except the last have a footer + if ($etp_blk->bhdr & 1) && ((UWord*)((char*)$etp_blk + $etp_blk_sz))[-1] != $etp_blk_sz + printf "ERROR: Invalid footer of free block at %#lx\n", $etp_blk + end + set $etp_prev_blk = $etp_blk + set $etp_blk = (Block_t*) ((char*)$etp_blk + $etp_blk_sz) + end + + if ((char*)$etp_blk + $etp_blk_sz) != ((char*)$etp_crr + ($etp_crr->chdr & ~7)) + printf "ERROR: Last block not at end of carrier\n" + set $etp_error_cnt = $etp_error_cnt + 1 + end + printf "Allocated blocks: %u\n", $etp_ablk_cnt + printf "Free blocks: %u\n", $etp_fblk_cnt + if $etp_error_cnt + printf "%u ERRORs reported above\n", $etp-error-cnt + end +end + +document etp-carrier-blocks +%--------------------------------------------------------------------------- +% Check and (maybe) print all memory blocks in carrier +% Args: (Carrier_t*) [1=be_silent] +%--------------------------------------------------------------------------- +end + + +############################################################################ # Toolbox parameter handling # diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam Binary files differindex 6ea8ea9773..ba45e4e011 100644 --- a/erts/preloaded/ebin/erts_internal.beam +++ b/erts/preloaded/ebin/erts_internal.beam diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam Binary files differindex 7f2d2740e1..26f779500c 100644 --- a/erts/preloaded/ebin/init.beam +++ b/erts/preloaded/ebin/init.beam diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index 67099093c5..4ff0513321 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -2264,6 +2264,7 @@ tuple_to_list(_Tuple) -> (system_architecture) -> string(); (threads) -> boolean(); (thread_pool_size) -> non_neg_integer(); + (tolerant_timeofday) -> enabled | disabled; (trace_control_word) -> non_neg_integer(); (update_cpu_info) -> changed | unchanged; (version) -> string(); diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl index e9044503b3..2c5bd82cf0 100644 --- a/erts/preloaded/src/erts_internal.erl +++ b/erts/preloaded/src/erts_internal.erl @@ -30,6 +30,7 @@ -export([await_port_send_result/3]). -export([cmp_term/2]). +-export([map_to_tuple_keys/1]). -export([port_command/3, port_connect/2, port_close/1, port_control/3, port_call/3, port_info/1, port_info/2]). @@ -169,3 +170,11 @@ check_process_code(_Module, _OptionList) -> cmp_term(_A,_B) -> erlang:nif_error(undefined). + +%% return the internal key tuple for map keys +-spec map_to_tuple_keys(M) -> Keys when + M :: map(), + Keys :: tuple(). + +map_to_tuple_keys(_M) -> + erlang:nif_error(undefined). diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl index ab8464956c..e95e11b3e6 100644 --- a/erts/preloaded/src/init.erl +++ b/erts/preloaded/src/init.erl @@ -1041,7 +1041,7 @@ start_em([]) -> ok. start_it([]) -> ok; start_it({eval,Bin}) -> - Str = binary_to_list(Bin), + Str = b2s(Bin), {ok,Ts,_} = erl_scan:string(Str), Ts1 = case reverse(Ts) of [{dot,_}|_] -> Ts; diff --git a/erts/vsn.mk b/erts/vsn.mk index a108b1d100..fff334c89f 100644 --- a/erts/vsn.mk +++ b/erts/vsn.mk @@ -17,7 +17,7 @@ # %CopyrightEnd% # -VSN = 6.0.1 +VSN = 6.0.2 # Port number 4365 in 4.2 # Port number 4366 in 4.3 |