aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/erlang.xml4
-rw-r--r--erts/emulator/beam/bif.tab1
-rw-r--r--erts/emulator/beam/break.c2
-rw-r--r--erts/emulator/beam/dist.c4
-rwxr-xr-xerts/emulator/beam/erl_bif_info.c4
-rw-r--r--erts/emulator/beam/erl_bif_os.c22
-rw-r--r--erts/emulator/beam/erl_process_dump.c46
-rw-r--r--erts/emulator/beam/sys.h2
-rw-r--r--erts/emulator/sys/unix/sys.c10
-rw-r--r--erts/emulator/sys/win32/sys_env.c18
-rw-r--r--erts/emulator/test/bif_SUITE.erl10
-rw-r--r--erts/emulator/test/hash_SUITE.erl6
-rw-r--r--erts/etc/unix/cerl.src30
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin54536 -> 54672 bytes
-rw-r--r--erts/preloaded/src/Makefile2
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl7
-rw-r--r--erts/test/z_SUITE.erl31
17 files changed, 167 insertions, 32 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index bc38055b62..cbb25c2cf2 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -4727,8 +4727,8 @@ true</pre>
<name name="statistics" arity="1" clause_i="6"/>
<fsummary>Information about the run-queue</fsummary>
<desc>
- <p>Returns the length of the run queue, that is, the number
- of processes that are ready to run.</p>
+ <p>Returns the total length of the run queues, that is, the number
+ of processes that are ready to run on all available run queues.</p>
</desc>
</func>
<func>
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index dc8e9101de..6037c08dd8 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -572,6 +572,7 @@ bif erlang:float_to_binary/2
bif erlang:binary_to_float/1
bif io:printable_range/0
+bif os:unsetenv/1
#
# Obsolete
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 99604fa3bc..b7e1092907 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -757,7 +757,7 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
return; /* Can't create the crash dump, skip it */
time(&now);
- erts_fdprintf(fd, "=erl_crash_dump:0.2\n%s", ctime(&now));
+ erts_fdprintf(fd, "=erl_crash_dump:0.3\n%s", ctime(&now));
if (file != NULL)
erts_fdprintf(fd, "The error occurred in file %s, line %d\n", file, line);
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index aabccac822..6ecf3f0722 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -1509,12 +1509,12 @@ int erts_net_message(Port *prt,
break;
}
rp = erts_pid2proc(NULL, 0, mon->pid, rp_locks);
+
+ erts_destroy_monitor(mon);
if (rp == NULL) {
break;
}
- erts_destroy_monitor(mon);
-
mon = erts_remove_monitor(&ERTS_P_MONITORS(rp), ref);
if (mon == NULL) {
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 5fbcbbe250..d7f1e2d971 100755
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -1771,7 +1771,11 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */
#if defined(PURIFY)
BIF_RET(erts_make_integer(purify_new_leaks(), BIF_P));
#elif defined(VALGRIND)
+# ifdef VALGRIND_DO_ADDED_LEAK_CHECK
+ VALGRIND_DO_ADDED_LEAK_CHECK;
+# else
VALGRIND_DO_LEAK_CHECK;
+# endif
BIF_RET(make_small(0));
#endif
} else if (*tp == am_fd) {
diff --git a/erts/emulator/beam/erl_bif_os.c b/erts/emulator/beam/erl_bif_os.c
index 1062d4379b..e07c622928 100644
--- a/erts/emulator/beam/erl_bif_os.c
+++ b/erts/emulator/beam/erl_bif_os.c
@@ -180,3 +180,25 @@ BIF_RETTYPE os_putenv_2(BIF_ALIST_2)
BIF_RET(am_true);
}
+BIF_RETTYPE os_unsetenv_1(BIF_ALIST_1)
+{
+ char *key_buf;
+ char buf[STATIC_BUF_SIZE];
+
+ key_buf = erts_convert_filename_to_native(BIF_ARG_1,buf,STATIC_BUF_SIZE,
+ ERTS_ALC_T_TMP,0,0,NULL);
+ if (!key_buf) {
+ BIF_ERROR(BIF_P, BADARG);
+ }
+
+ if (erts_sys_unsetenv(key_buf)) {
+ if (key_buf != buf) {
+ erts_free(ERTS_ALC_T_TMP, key_buf);
+ }
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ if (key_buf != buf) {
+ erts_free(ERTS_ALC_T_TMP, key_buf);
+ }
+ BIF_RET(am_true);
+}
diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c
index 6cd0d23b97..2f3cf23b00 100644
--- a/erts/emulator/beam/erl_process_dump.c
+++ b/erts/emulator/beam/erl_process_dump.c
@@ -34,8 +34,8 @@
#define ERTS_WANT_EXTERNAL_TAGS
#include "external.h"
-#define WORD_FMT "%X"
-#define ADDR_FMT "%X"
+#define PTR_FMT "%bpX"
+#define ETERM_FMT "%beX"
#define OUR_NIL _make_header(0,_TAG_HEADER_FLOAT)
@@ -210,9 +210,9 @@ static void
dump_element(int to, void *to_arg, Eterm x)
{
if (is_list(x)) {
- erts_print(to, to_arg, "H" WORD_FMT, list_val(x));
+ erts_print(to, to_arg, "H" PTR_FMT, list_val(x));
} else if (is_boxed(x)) {
- erts_print(to, to_arg, "H" WORD_FMT, boxed_val(x));
+ erts_print(to, to_arg, "H" PTR_FMT, boxed_val(x));
} else if (is_immed(x)) {
if (is_atom(x)) {
unsigned char* s = atom_tab(atom_val(x))->name;
@@ -311,7 +311,7 @@ heap_dump(int to, void *to_arg, Eterm x)
} else if (is_list(x)) {
ptr = list_val(x);
if (ptr[0] != OUR_NIL) {
- erts_print(to, to_arg, ADDR_FMT ":l", ptr);
+ erts_print(to, to_arg, PTR_FMT ":l", ptr);
dump_element(to, to_arg, ptr[0]);
erts_putc(to, to_arg, '|');
dump_element(to, to_arg, ptr[1]);
@@ -330,12 +330,12 @@ heap_dump(int to, void *to_arg, Eterm x)
ptr = boxed_val(x);
hdr = *ptr;
if (hdr != OUR_NIL) { /* If not visited */
- erts_print(to, to_arg, ADDR_FMT ":", ptr);
+ erts_print(to, to_arg, PTR_FMT ":", ptr);
if (is_arity_value(hdr)) {
Uint i;
Uint arity = arityval(hdr);
- erts_print(to, to_arg, "t" WORD_FMT ":", arity);
+ erts_print(to, to_arg, "t" ETERM_FMT ":", arity);
for (i = 1; i <= arity; i++) {
dump_element(to, to_arg, ptr[i]);
if (is_immed(ptr[i])) {
@@ -388,21 +388,43 @@ heap_dump(int to, void *to_arg, Eterm x)
val->flags = (UWord) all_binaries;
all_binaries = val;
}
- erts_print(to, to_arg, "Yc%X:%X:%X", val,
+ erts_print(to, to_arg,
+ "Yc" PTR_FMT ":" PTR_FMT ":" PTR_FMT,
+ val,
pb->bytes - (byte *)val->orig_bytes,
size);
} else if (tag == SUB_BINARY_SUBTAG) {
ErlSubBin* Sb = (ErlSubBin *) binary_val(x);
- Eterm* real_bin = binary_val(Sb->orig);
+ Eterm* real_bin;
void* val;
+ /*
+ * Must use boxed_val() here, because the original
+ * binary may have been visited and have had its
+ * header word changed to OUR_NIL (in which case
+ * binary_val() will cause an assertion failure in
+ * the DEBUG emulator).
+ */
+
+ real_bin = boxed_val(Sb->orig);
+
if (thing_subtag(*real_bin) == REFC_BINARY_SUBTAG) {
+ /*
+ * Unvisited REFC_BINARY: Point directly to
+ * the binary.
+ */
ProcBin* pb = (ProcBin *) real_bin;
val = pb->val;
- } else { /* Heap binary */
+ } else {
+ /*
+ * Heap binary or visited REFC binary: Point
+ * to heap binary or ProcBin on the heap.
+ */
val = real_bin;
}
- erts_print(to, to_arg, "Ys%X:%X:%X", val, Sb->offs, size);
+ erts_print(to, to_arg,
+ "Ys" PTR_FMT ":" PTR_FMT ":" PTR_FMT,
+ val, Sb->offs, size);
}
erts_putc(to, to_arg, '\n');
*ptr = OUR_NIL;
@@ -438,7 +460,7 @@ dump_binaries(int to, void *to_arg, Binary* current)
long size = current->orig_size;
byte* bytes = (byte*) current->orig_bytes;
- erts_print(to, to_arg, "=binary:%X\n", current);
+ 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]);
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 9561c0be96..d22f125945 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -750,6 +750,8 @@ int erts_sys_getenv(char *key, char *value, size_t *size);
int erts_sys_getenv_raw(char *key, char *value, size_t *size);
/* erts_sys_getenv__() is only allowed to be used in early init phase */
int erts_sys_getenv__(char *key, char *value, size_t *size);
+/* erst_sys_unsetenv() returns 0 on success and a value != 0 on failure. */
+int erts_sys_unsetenv(char *key);
/* Easier to use, but not as efficient, environment functions */
char *erts_read_env(char *key);
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 401b37b9d2..61f9f6a59a 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -2489,6 +2489,16 @@ erts_sys_getenv(char *key, char *value, size_t *size)
return res;
}
+int
+erts_sys_unsetenv(char *key)
+{
+ int res;
+ erts_smp_rwmtx_rwlock(&environ_rwmtx);
+ res = unsetenv(key);
+ erts_smp_rwmtx_rwunlock(&environ_rwmtx);
+ return res;
+}
+
void
sys_init_io(void)
{
diff --git a/erts/emulator/sys/win32/sys_env.c b/erts/emulator/sys/win32/sys_env.c
index 754f4c6e4c..9f977ad6c8 100644
--- a/erts/emulator/sys/win32/sys_env.c
+++ b/erts/emulator/sys/win32/sys_env.c
@@ -141,6 +141,24 @@ void fini_getenv_state(GETENV_STATE *state)
erts_smp_rwmtx_runlock(&environ_rwmtx);
}
+int erts_sys_unsetenv(char *key)
+{
+ int res = 0;
+ WCHAR *wkey = (WCHAR *) key;
+
+ SetLastError(0);
+ erts_smp_rwmtx_rlock(&environ_rwmtx);
+ GetEnvironmentVariableW(wkey,
+ NULL,
+ 0);
+ if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
+ res = (SetEnvironmentVariableW(wkey,
+ NULL) ? 0 : 1);
+ }
+ erts_smp_rwmtx_runlock(&environ_rwmtx);
+ return res;
+}
+
char*
win_build_environment(char* new_env)
{
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index 02c6de8cb1..fbc229bc53 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -388,8 +388,12 @@ os_env(Config) when is_list(Config) ->
false -> ?line ok;
BadVal -> ?line ?t:fail(BadVal)
end,
- %% os:putenv and os:getenv currently uses a temp buf of size 1024
- %% for storing key+value
+ true = os:putenv(EnvVar1, "mors"),
+ true = os:unsetenv(EnvVar1),
+ false = os:getenv(EnvVar1),
+ true = os:unsetenv(EnvVar1), % unset unset variable
+ %% os:putenv, os:getenv and os:unsetenv currently use a temp
+ %% buffer of size 1024 for storing key+value
?line os_env_long(1010, 1030, "hej hopp").
os_env_long(Min, Max, _Value) when Min > Max ->
@@ -398,7 +402,7 @@ os_env_long(Min, Max, Value) ->
?line EnvVar = lists:duplicate(Min, $X),
?line true = os:putenv(EnvVar, Value),
?line Value = os:getenv(EnvVar),
- ?line true = os:putenv(EnvVar, ""),
+ true = os:unsetenv(EnvVar),
?line os_env_long(Min+1, Max, Value).
otp_7526(doc) ->
diff --git a/erts/emulator/test/hash_SUITE.erl b/erts/emulator/test/hash_SUITE.erl
index 43c9d64af7..738c9c8b16 100644
--- a/erts/emulator/test/hash_SUITE.erl
+++ b/erts/emulator/test/hash_SUITE.erl
@@ -32,7 +32,7 @@
%%
-module(hash_SUITE).
-export([basic_test/0,cmp_test/1,range_test/0,spread_test/1,
- phash2_test/0, otp_5292_test/0, bit_level_binaries/0,
+ phash2_test/0, otp_5292_test/0,
otp_7127_test/0]).
-compile({nowarn_deprecated_function, {erlang,hash,2}}).
@@ -152,7 +152,7 @@ otp_5292(Config) when is_list(Config) ->
%% Test hashing bit-level binaries.
bit_level_binaries(Config) when is_list(Config) ->
- bit_level_binaries().
+ bit_level_binaries_do().
otp_7127(suite) ->
[];
@@ -537,7 +537,7 @@ hash_int(Start, End, F) ->
md5(T) ->
erlang:md5(term_to_binary(T)).
-bit_level_binaries() ->
+bit_level_binaries_do() ->
[3511317,7022633,14044578,28087749,56173436,112344123,90467083|_] =
bit_level_all_different(fun erlang:hash/2),
[3511317,7022633,14044578,28087749,56173436,112344123,90467083|_] =
diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src
index 41baa323ed..be8343e87e 100644
--- a/erts/etc/unix/cerl.src
+++ b/erts/etc/unix/cerl.src
@@ -33,6 +33,7 @@
# You have to start beam in gdb using "run".
# -rgdb Run the debug compiled emulator in gdb.
# You have to start beam in gdb using "run".
+# -dump Dump the bt of all threads in a core.
# -break F Run the debug compiled emulator in emacs and gdb and set break.
# The session is started, i.e. "run" is already don for you.
# -xxgdb FIXME currently disabled
@@ -178,6 +179,12 @@ while [ $# -gt 0 ]; do
cargs="$cargs -frmptr"
TYPE=.frmptr
;;
+ "-dump")
+ shift
+ GDB=dump
+ core="$1"
+ shift
+ ;;
"-gdb")
shift
GDB=egdb
@@ -331,7 +338,7 @@ elif [ "x$GDB" = "xgdb" ]; then
echo "source $ROOTDIR/erts/etc/unix/etp-commands" > $cmdfile
# Fire up gdb in emacs...
exec gdb $GDBBP -x $cmdfile $gdbcmd
-else
+elif [ "x$GDB" = "xegdb" ]; then
if [ "x$EMACS" = "x" ]; then
EMACS=emacs
fi
@@ -339,7 +346,7 @@ else
case "x$core" in
x)
# Get emu args to use from erlexec...
- beam_args=`$EXEC -emu_args_exit ${1+"$@"}`
+ beam_args=`$EXEC -emu_args_exit ${1+"$@"} | tr '\n' ' '`
gdbcmd="(insert-string \"set args $beam_args\") \
(comint-send-input)"
;;
@@ -372,4 +379,23 @@ else
(comint-send-input)"
# Fire up gdb in emacs...
exec $EMACS --eval "(progn (gdb \"gdb $GDBARGS$EMU_NAME\") $gdbcmd)"
+elif [ "x$GDB" = "xdump" ]; then
+ cmdfile="/tmp/.cerlgdb.$$"
+ case "x$core" in
+ x/*)
+ gdbcmd="$EMU_NAME ${core}"
+ ;;
+ *)
+ dir=`pwd`
+ gdbcmd="$EMU_NAME ${dir}/${core}"
+ ;;
+ esac
+ echo "set width 0
+set height 0
+set verbose off
+
+source $ROOTDIR/erts/etc/unix/etp-commands
+thread apply all bt
+" > $cmdfile
+ exec gdb --batch --command=$cmdfile $gdbcmd
fi
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index f51ccfe8ce..ece0e6d5e8 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/src/Makefile b/erts/preloaded/src/Makefile
index c1580b1495..4ea2d41075 100644
--- a/erts/preloaded/src/Makefile
+++ b/erts/preloaded/src/Makefile
@@ -68,7 +68,7 @@ KERNEL_SRC=$(ERL_TOP)/lib/kernel/src
KERNEL_INCLUDE=$(ERL_TOP)/lib/kernel/include
STDLIB_INCLUDE=$(ERL_TOP)/lib/stdlib/include
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE)
+ERL_COMPILE_FLAGS += +warn_obsolete_guard +debug_info -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE)
debug opt: $(TARGET_FILES)
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index e8ddfc4a57..fc43d1d4fa 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -1439,7 +1439,12 @@ normalize(Name, Acc) ->
[Atom | Rest] when is_atom(Atom) ->
normalize(atom_to_list(Atom) ++ Rest, Acc);
[$\\ | Chars] ->
- normalize(Chars, [$/ | Acc]);
+ case erlang:system_info(os_type) of
+ {win32, _} ->
+ normalize(Chars, [$/ | Acc]);
+ _ ->
+ normalize(Chars, [$\\ | Acc])
+ end;
[Char | Chars] ->
normalize(Chars, [Char | Acc]);
[] ->
diff --git a/erts/test/z_SUITE.erl b/erts/test/z_SUITE.erl
index ccf22a9b6b..da72b18f05 100644
--- a/erts/test/z_SUITE.erl
+++ b/erts/test/z_SUITE.erl
@@ -231,6 +231,20 @@ mod_time_list(F) ->
str_strip(S) ->
string:strip(string:strip(string:strip(S), both, $\n), both, $\r).
+dump_core(#core_search_conf{ cerl = false }, _) ->
+ ok;
+dump_core(_, {ignore, _Core}) ->
+ ok;
+dump_core(#core_search_conf{ cerl = Cerl }, Core) ->
+ Dump = case test_server:is_debug() of
+ true ->
+ os:cmd(Cerl ++ " -debug -dump " ++ Core);
+ _ ->
+ os:cmd(Cerl ++ " -dump " ++ Core)
+ end,
+ ct:log("~s~n~n~s",[Core,Dump]).
+
+
format_core(Conf, {ignore, Core}) ->
format_core(Conf, Core, "[ignored] ");
format_core(Conf, Core) ->
@@ -254,11 +268,16 @@ core_file_search(#core_search_conf{search_dir = Base,
extra_search_dir = XBase,
cerl = Cerl,
run_by_ts = RunByTS} = Conf) ->
- case Cerl of
- false -> ok;
- _ -> catch io:format("A cerl script that probably can be used for "
- "inspection of emulator cores:~n ~s~n",
- [Cerl])
+ case {Cerl,test_server:is_debug()} of
+ {false,_} -> ok;
+ {_,true} ->
+ catch io:format("A cerl script that probably can be used for "
+ "inspection of emulator cores:~n ~s -debug~n",
+ [Cerl]);
+ _ ->
+ catch io:format("A cerl script that probably can be used for "
+ "inspection of emulator cores:~n ~s~n",
+ [Cerl])
end,
io:format("Searching for core-files in: ~s~s~n",
[case XBase of
@@ -329,6 +348,8 @@ core_file_search(#core_search_conf{search_dir = Base,
["Ignored core-files found:",
lists:reverse(ICores)]
end]),
+
+ lists:foreach(fun(C) -> dump_core(Conf,C) end, Cores),
case {RunByTS, ICores, FCores} of
{true, [], []} -> ok;
{true, _, []} -> {comment, Res};