diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/erl_bif_info.c | 15 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_util.c | 12 | ||||
-rw-r--r-- | erts/emulator/beam/erl_db_util.h | 30 | ||||
-rw-r--r-- | erts/emulator/beam/erl_node_tables.c | 2 | ||||
-rw-r--r-- | erts/emulator/test/socket_SUITE.erl | 28 | ||||
-rw-r--r-- | erts/etc/common/erlc.c | 13 |
6 files changed, 73 insertions, 27 deletions
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 7db8142d28..b06b5fc1ab 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -164,20 +164,21 @@ static Eterm current_stacktrace(ErtsHeapFactory *hfact, Process* rp, Eterm erts_bld_bin_list(Uint **hpp, Uint *szp, ErlOffHeap* oh, Eterm tail) { - struct erl_off_heap_header* ohh; + union erl_off_heap_ptr u; Eterm res = tail; Eterm tuple; + struct erts_tmp_aligned_offheap tmp; - for (ohh = oh->first; ohh; ohh = ohh->next) { - if (ohh->thing_word == HEADER_PROC_BIN) { - ProcBin* pb = (ProcBin*) ohh; - Eterm val = erts_bld_uword(hpp, szp, (UWord) pb->val); - Eterm orig_size = erts_bld_uint(hpp, szp, pb->val->orig_size); + for (u.hdr = oh->first; u.hdr; u.hdr = u.hdr->next) { + erts_align_offheap(&u, &tmp); + if (u.hdr->thing_word == HEADER_PROC_BIN) { + Eterm val = erts_bld_uword(hpp, szp, (UWord) u.pb->val); + Eterm orig_size = erts_bld_uint(hpp, szp, u.pb->val->orig_size); if (szp) *szp += 4+2; if (hpp) { - Uint refc = (Uint) erts_refc_read(&pb->val->intern.refc, 1); + Uint refc = (Uint) erts_refc_read(&u.pb->val->intern.refc, 1); tuple = TUPLE3(*hpp, val, orig_size, make_small(refc)); res = CONS(*hpp + 4, tuple, res); *hpp += 4+2; diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c index 1ea7074d21..ed09a34ae4 100644 --- a/erts/emulator/beam/erl_db_util.c +++ b/erts/emulator/beam/erl_db_util.c @@ -3285,22 +3285,15 @@ Eterm db_copy_element_from_ets(DbTableCommon* tb, Process* p, void db_cleanup_offheap_comp(DbTerm* obj) { union erl_off_heap_ptr u; - ProcBin tmp; + struct erts_tmp_aligned_offheap tmp; for (u.hdr = obj->first_oh; u.hdr; u.hdr = u.hdr->next) { - if ((UWord)u.voidp % sizeof(Uint) != 0) { /* unaligned ptr */ - sys_memcpy(&tmp, u.voidp, sizeof(tmp)); - /* Warning, must pass (void*)-variable to memcpy. Otherwise it will - cause Bus error on Sparc due to false compile time assumptions - about word aligned memory (type cast is not enough) */ - u.pb = &tmp; - } + erts_align_offheap(&u, &tmp); switch (thing_subtag(u.hdr->thing_word)) { case REFC_BINARY_SUBTAG: erts_bin_release(u.pb->val); break; case FUN_SUBTAG: - ASSERT(u.pb != &tmp); if (erts_refc_dectest(&u.fun->fe->refc, 0) == 0) { erts_erase_fun_entry(u.fun->fe); } @@ -3311,7 +3304,6 @@ void db_cleanup_offheap_comp(DbTerm* obj) break; default: ASSERT(is_external_header(u.hdr->thing_word)); - ASSERT(u.pb != &tmp); erts_deref_node_entry(u.ext->node, make_boxed(u.ep)); break; } diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h index 7a21de9a6c..f038dba89a 100644 --- a/erts/emulator/beam/erl_db_util.h +++ b/erts/emulator/beam/erl_db_util.h @@ -543,6 +543,17 @@ ERTS_GLB_INLINE Eterm erts_db_make_match_prog_ref(Process *p, Binary *mp, Eterm ERTS_GLB_INLINE Binary *erts_db_get_match_prog_binary(Eterm term); ERTS_GLB_INLINE Binary *erts_db_get_match_prog_binary_unchecked(Eterm term); +/* @brief Ensure off-heap header is word aligned, make a temporary copy if not. + * Needed when inspecting ETS off-heap lists that may contain unaligned + * ProcBins if table is 'compressed'. + */ +struct erts_tmp_aligned_offheap +{ + ProcBin proc_bin; +}; +ERTS_GLB_INLINE void erts_align_offheap(union erl_off_heap_ptr*, + struct erts_tmp_aligned_offheap* tmp); + #if ERTS_GLB_INLINE_INCL_FUNC_DEF /* @@ -575,6 +586,25 @@ erts_db_get_match_prog_binary(Eterm term) return bp; } +ERTS_GLB_INLINE void +erts_align_offheap(union erl_off_heap_ptr* ohp, + struct erts_tmp_aligned_offheap* tmp) +{ + if ((UWord)ohp->voidp % sizeof(UWord) != 0) { + /* + * ETS store word unaligned ProcBins in its compressed format. + * Make a temporary aligned copy. + * + * Warning, must pass (void*)-variable to memcpy. Otherwise it will + * cause Bus error on Sparc due to false compile time assumptions + * about word aligned memory (type cast is not enough). + */ + sys_memcpy(tmp, ohp->voidp, sizeof(*tmp)); + ASSERT(tmp->proc_bin.thing_word == HEADER_PROC_BIN); + ohp->pb = &tmp->proc_bin; + } +} + #endif /* diff --git a/erts/emulator/beam/erl_node_tables.c b/erts/emulator/beam/erl_node_tables.c index 50e9812534..8863e219e2 100644 --- a/erts/emulator/beam/erl_node_tables.c +++ b/erts/emulator/beam/erl_node_tables.c @@ -1509,10 +1509,12 @@ static void insert_offheap(ErlOffHeap *oh, int type, Eterm id) { union erl_off_heap_ptr u; + struct erts_tmp_aligned_offheap tmp; struct insert_offheap2_arg a; a.type = BIN_REF; for (u.hdr = oh->first; u.hdr; u.hdr = u.hdr->next) { + erts_align_offheap(&u, &tmp); switch (thing_subtag(u.hdr->thing_word)) { case REF_SUBTAG: if (ErtsIsDistEntryBinary(u.mref->mb)) diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 4980ea2a82..124ae09951 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -1776,7 +1776,7 @@ quiet_mode(Config) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% A simple test case that tests that the global debug can be channged. +%% A simple test case that tests that the global debug can be changed. %% At the same time, it will test the info function (since it uses it %% for verification). @@ -1794,7 +1794,8 @@ api_m_debug(_Config) when is_list(_Config) -> %% For some reason this test case triggers a gcc bug, which causes %% a segfault, on an ancient Fedora 16 VM. So, check the version of gcc... -%% Not pretty, but the simplest way to skip (without actually testing for the host). +%% Not pretty, but the simplest way to skip (without actually testing +%% for the host). has_bugfree_gcc() -> has_bugfree_gcc(os:type()). @@ -19470,6 +19471,7 @@ traffic_ping_pong_large_send_and_recv_tcp4(_Config) when is_list(_Config) -> Msg = l2b(?TPP_LARGE), Num = ?TPP_LARGE_NUM, tc_try(traffic_ping_pong_large_send_and_recv_tcp4, + fun() -> is_old_fedora16() end, fun() -> InitState = #{domain => inet, proto => tcp, @@ -19496,7 +19498,8 @@ traffic_ping_pong_large_send_and_recv_tcp6(_Config) when is_list(_Config) -> Msg = l2b(?TPP_LARGE), Num = ?TPP_LARGE_NUM, tc_try(traffic_ping_pong_large_send_and_recv_tcp6, - fun() -> has_support_ipv6() end, + fun() -> is_old_fedora16(), + has_support_ipv6() end, fun() -> ?TT(?SECS(45)), InitState = #{domain => inet6, @@ -19545,9 +19548,28 @@ traffic_ping_pong_large_host_cond() -> traffic_ping_pong_large_host_cond({unix, sunos}, _) -> skip("TC does not work on platform"); +traffic_ping_pong_large_host_cond({unix, linux}, _) -> + traffic_ping_pong_large_host_cond2(string:trim(os:cmd("cat /etc/issue"))); traffic_ping_pong_large_host_cond(_, _) -> ok. +traffic_ping_pong_large_host_cond2("Welcome to SUSE Linux Enterprise Server 10 SP1 (i586)" ++ _) -> + skip("TC does not work on platform"); +traffic_ping_pong_large_host_cond2("Fedora release 16 " ++ _) -> + skip("Very slow VM"); +traffic_ping_pong_large_host_cond2(_) -> + ok. + + +is_old_fedora16() -> + is_old_fedora16(string:trim(os:cmd("cat /etc/issue"))). + +%% We actually only have one host running this, a slow VM. +is_old_fedora16("Fedora release 16 " ++ _) -> + skip("Very slow VM"); +is_old_fedora16(_) -> + ok. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% This test case is intended to test that the sendto and recvfrom diff --git a/erts/etc/common/erlc.c b/erts/etc/common/erlc.c index a9ee023727..56060497f3 100644 --- a/erts/etc/common/erlc.c +++ b/erts/etc/common/erlc.c @@ -233,10 +233,6 @@ int main(int argc, char** argv) if (strlen(emulator) >= MAXPATHLEN) error("Value of environment variable ERLC_EMULATOR is too large"); -#ifndef __WIN32__ - emulator = find_executable(emulator); -#endif - /* * Add scriptname to env */ @@ -256,7 +252,10 @@ int main(int argc, char** argv) #ifdef __WIN32__ set_env("ERLC_CONFIGURATION", get_env("PATH")); #else - set_env("ERLC_CONFIGURATION", emulator); + { + char* full_path_emulator = find_executable(emulator); + set_env("ERLC_CONFIGURATION", full_path_emulator); + } #endif /* @@ -595,7 +594,7 @@ run_erlang(char* progname, char** argv) } return status; #else - execv(progname, argv); + execvp(progname, argv); error("Error %d executing \'%s\'.", errno, progname); return 2; #endif @@ -949,7 +948,7 @@ start_compile_server(char* node_name, char** argv) } #else if (fork() == 0) { - execv(eargv[0], eargv); + execvp(eargv[0], eargv); error("Error %d executing \'%s\'.", errno, progname); } #endif |