diff options
Diffstat (limited to 'erts')
23 files changed, 302 insertions, 203 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index a603d5c2b8..8c01d77721 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -3909,7 +3909,7 @@ os_prompt%</pre> <item> <p>Return the current call stack back-trace (<em>stacktrace</em>) of the process. The stack has the same format as returned by - <seealso marker="#get_stacktrace/1">erlang:get_stacktrace/0</seealso>. + <seealso marker="#get_stacktrace/0">erlang:get_stacktrace/0</seealso>. </p> </item> <tag><c>{dictionary, Dictionary}</c></tag> diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index a5d8217545..45cf540994 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -426,7 +426,7 @@ endif @set -e ; cd zlib && $(MAKE) clean rm -f $(OBJS) $(OBJDIR)/libepcre.a -.PHONY: all zlib clean +.PHONY: all zlib clean valgrind docs: diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index e80eae0b86..7510f6b724 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -371,11 +371,17 @@ typedef struct erl_drv_entry { #ifndef ERL_DRIVER_TYPES_ONLY #if defined(VXWORKS) -# define DRIVER_INIT(DRIVER_NAME) ErlDrvEntry* DRIVER_NAME ## _init(void) +# define DRIVER_INIT(DRIVER_NAME) \ + ErlDrvEntry* DRIVER_NAME ## _init(void); \ + ErlDrvEntry* DRIVER_NAME ## _init(void) #elif defined(__WIN32__) -# define DRIVER_INIT(DRIVER_NAME) __declspec(dllexport) ErlDrvEntry* driver_init(void) +# define DRIVER_INIT(DRIVER_NAME) \ + __declspec(dllexport) ErlDrvEntry* driver_init(void); \ + __declspec(dllexport) ErlDrvEntry* driver_init(void) #else -# define DRIVER_INIT(DRIVER_NAME) ErlDrvEntry* driver_init(void) +# define DRIVER_INIT(DRIVER_NAME) \ + ErlDrvEntry* driver_init(void); \ + ErlDrvEntry* driver_init(void) #endif /* diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index eb2b945877..9590aa4a74 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -910,7 +910,18 @@ minor_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl) * XXX: WARNING: If HiPE starts storing other non-Erlang values on the * nstack, such as floats, then this will have to be changed. */ -#define offset_nstack(p,offs,area,area_size) offset_heap_ptr(hipe_nstack_start((p)),hipe_nstack_used((p)),(offs),(area),(area_size)) +static ERTS_INLINE void offset_nstack(Process* p, Sint offs, + char* area, Uint area_size) +{ + if (p->hipe.nstack) { + ASSERT(p->hipe.nsp && p->hipe.nstend); + offset_heap_ptr(hipe_nstack_start(p), hipe_nstack_used(p), + offs, area, area_size); + } + else { + ASSERT(!p->hipe.nsp && !p->hipe.nstend); + } +} #else /* !HIPE */ diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 2b5e65b11a..a2b08fcf56 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -731,7 +731,6 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) int reds = ERTS_PORT_REDS_EXECUTE; erts_aint_t io_tasks_executed = 0; int fpe_was_unmasked; - ErtsPortTaskExeBlockData blk_data = {runq, NULL}; ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(runq)); @@ -965,8 +964,6 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) #endif done: - blk_data.resp = &res; - ERTS_SMP_LC_ASSERT(erts_smp_lc_runq_is_locked(runq)); ERTS_PORT_REDUCTIONS_EXECUTED(runq, reds); diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index b487dbf054..70c3e7612f 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -544,7 +544,7 @@ send_to_port(Process *c_p, Eterm message, */ static void -profile_send(Eterm message) { +profile_send(Eterm profiler, Eterm message) { Uint sz = 0; ErlHeapFragment *bp = NULL; Uint *hp = NULL; @@ -552,8 +552,6 @@ profile_send(Eterm message) { Process *profile_p = NULL; ErlOffHeap *off_heap = NULL; - Eterm profiler = erts_get_system_profile(); - if (is_internal_port(profiler)) { Port *profiler_port = NULL; @@ -2583,6 +2581,7 @@ profile_scheduler(Eterm scheduler_id, Eterm state) { Uint Ms, s, us; #ifndef ERTS_SMP + Eterm profiler; #define LOCAL_HEAP_SIZE (4 + 7) DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); UseTmpHeapNoproc(LOCAL_HEAP_SIZE); @@ -2617,7 +2616,8 @@ profile_scheduler(Eterm scheduler_id, Eterm state) { make_small(active_sched), timestamp); hp += 7; #ifndef ERTS_SMP - profile_send(msg); + profiler = erts_get_system_profile(); + profile_send(profiler, msg); UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); #undef LOCAL_HEAP_SIZE #else @@ -2632,6 +2632,7 @@ profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint M Eterm *hp, msg, timestamp; #ifndef ERTS_SMP + Eterm profiler; #define LOCAL_HEAP_SIZE (4 + 7) DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); UseTmpHeapNoproc(LOCAL_HEAP_SIZE); @@ -2652,7 +2653,8 @@ profile_scheduler_q(Eterm scheduler_id, Eterm state, Eterm no_schedulers, Uint M timestamp = TUPLE3(hp, make_small(Ms), make_small(s), make_small(us)); hp += 4; msg = TUPLE6(hp, am_profile, am_scheduler, scheduler_id, state, no_schedulers, timestamp); hp += 7; #ifndef ERTS_SMP - profile_send(msg); + profiler = erts_get_system_profile(); + profile_send(profiler, msg); UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); #undef LOCAL_HEAP_SIZE #else @@ -2895,6 +2897,7 @@ profile_runnable_port(Port *p, Eterm status) { Eterm count = make_small(0); #ifndef ERTS_SMP + Eterm profiler; #define LOCAL_HEAP_SIZE (4 + 6) DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); @@ -2919,7 +2922,8 @@ profile_runnable_port(Port *p, Eterm status) { msg = TUPLE5(hp, am_profile, p->id, status, count, timestamp); hp += 6; #ifndef ERTS_SMP - profile_send(msg); + profiler = erts_get_system_profile(); + profile_send(profiler, msg); UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); #undef LOCAL_HEAP_SIZE #else @@ -2934,6 +2938,7 @@ profile_runnable_proc(Process *p, Eterm status){ Uint Ms, s, us; Eterm *hp, msg, timestamp; Eterm where = am_undefined; + Eterm profiler; #ifndef ERTS_SMP #define LOCAL_HEAP_SIZE (4 + 6 + 4) @@ -2946,6 +2951,12 @@ profile_runnable_proc(Process *p, Eterm status){ ErlHeapFragment *bp; Uint hsz = 4 + 6 + 4; #endif + profiler = erts_get_system_profile(); + + /* Do not profile profiler pid */ + if (profiler == p->id) { + return; + } if (!p->current) { p->current = find_function_from_pc(p->i); @@ -2972,7 +2983,7 @@ profile_runnable_proc(Process *p, Eterm status){ timestamp = TUPLE3(hp, make_small(Ms), make_small(s), make_small(us)); hp += 4; msg = TUPLE5(hp, am_profile, p->id, status, where, timestamp); hp += 6; #ifndef ERTS_SMP - profile_send(msg); + profile_send(profiler, msg); UnUseTmpHeapNoproc(LOCAL_HEAP_SIZE); #undef LOCAL_HEAP_SIZE #else diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 49cd0e5f53..b23b1f628d 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 1996-2011. All Rights Reserved. + * Copyright Ericsson AB 1996-2012. 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 @@ -818,6 +818,11 @@ erts_smp_xports_unlock(Port *prt) #define SET_VEC(iov, bv, bin, ptr, len, vlen) do { \ (iov)->iov_base = (ptr); \ (iov)->iov_len = (len); \ + if (sizeof((iov)->iov_len) < sizeof(len) \ + /* Check if (len) overflowed (iov)->iov_len */ \ + && ((len) >> (sizeof((iov)->iov_len)*CHAR_BIT)) != 0) { \ + goto L_overflow; \ + } \ *(bv)++ = (bin); \ (iov)++; \ (vlen)++; \ @@ -1146,11 +1151,21 @@ int erts_write_to_port(Eterm caller_id, Port *p, Eterm list) ivp[0].iov_len = 0; bvp[0] = NULL; ev.vsize = io_list_to_vec(list, ivp+1, bvp+1, cbin, blimit); + if (ev.vsize < 0) { + if (ivp != iv) { + erts_free(ERTS_ALC_T_TMP, (void *) ivp); + } + if (bvp != bv) { + erts_free(ERTS_ALC_T_TMP, (void *) bvp); + } + driver_free_binary(cbin); + goto bad_value; + } ev.vsize++; #if 0 /* This assertion may say something useful, but it can be falsified during the emulator test suites. */ - ASSERT((ev.vsize >= 0) && (ev.vsize == vsize)); + ASSERT(ev.vsize == vsize); #endif ev.size = size; /* total size */ ev.iov = ivp; @@ -3912,7 +3927,7 @@ int driver_pushqv(ErlDrvPort ix, ErlIOVec* vec, ErlDrvSizeT skip) ErlDrvSizeT driver_deq(ErlDrvPort ix, ErlDrvSizeT size) { ErlIOQueue* q = drvport2ioq(ix); - int len; + ErlDrvSizeT len; if ((q == NULL) || (q->size < size)) return -1; diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c index b132991a3b..36ed108b76 100644 --- a/erts/emulator/drivers/common/efile_drv.c +++ b/erts/emulator/drivers/common/efile_drv.c @@ -1385,7 +1385,11 @@ static void invoke_writev(void *data) { size = d->c.writev.size; } - /* Copy the io vector to avoid locking the port que while writing */ + /* Copy the io vector to avoid locking the port que while writing, + * also, both we and efile_writev might/will change the SysIOVec + * when segmenting or due to partial write and we do not want to + * tamper with the actual queue that we get from driver_peekq + */ MUTEX_LOCK(d->c.writev.q_mtx); /* Lock before accessing the port queue */ iov0 = driver_peekq(d->c.writev.port, &iovlen); @@ -1424,7 +1428,7 @@ static void invoke_writev(void *data) { } else { d->result_ok = efile_writev(&d->errInfo, d->flags, (int) d->fd, - iov, iovcnt, size); + iov, iovcnt); } } else if (iovlen == 0) { d->result_ok = 1; diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h index 3868b38137..69ad02633c 100644 --- a/erts/emulator/drivers/common/erl_efile.h +++ b/erts/emulator/drivers/common/erl_efile.h @@ -162,7 +162,7 @@ int efile_write_info(Efile_error* errInfo, Efile_info* pInfo, char *name); int efile_write(Efile_error* errInfo, int flags, int fd, char* buf, size_t count); int efile_writev(Efile_error* errInfo, int flags, int fd, - SysIOVec* iov, int iovcnt, size_t size); + SysIOVec* iov, int iovcnt); int efile_read(Efile_error* errInfo, int flags, int fd, char* buf, size_t count, size_t* pBytesRead); int efile_seek(Efile_error* errInfo, int fd, diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index eeaa4d24ea..47a99fdbe6 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -6194,6 +6194,7 @@ static int sctp_set_opts(inet_descriptor* desc, char* ptr, int len) type = SCTP_DEFAULT_SEND_PARAM; arg_ptr = (char*) (&arg.sri); arg_sz = sizeof ( arg.sri); + VALGRIND_MAKE_MEM_DEFINED(arg_ptr, arg_sz); /*suppress "uninitialised bytes"*/ break; } case SCTP_OPT_EVENTS: @@ -10299,7 +10300,6 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len) cmsg.hdr.cmsg_level = IPPROTO_SCTP; cmsg.hdr.cmsg_type = SCTP_SNDRCV; cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(*sri)); - VALGRIND_MAKE_MEM_DEFINED(&cmsg, (char*)sri - (char*)&cmsg); /*suppress padding as "uninitialised bytes"*/ data_len = (buf + len) - ptr; /* The whole msg. @@ -10313,6 +10313,7 @@ static void packet_inet_command(ErlDrvData e, char* buf, ErlDrvSizeT len) mhdr.msg_iovlen = 1; mhdr.msg_control = cmsg.ancd; /* For ancilary data */ mhdr.msg_controllen = cmsg.hdr.cmsg_len; + VALGRIND_MAKE_MEM_DEFINED(mhdr.msg_control, mhdr.msg_controllen); /*suppress "uninitialised bytes"*/ mhdr.msg_flags = 0; /* Not used with "sendmsg" */ /* Now do the actual sending. NB: "flags" in "sendmsg" itself are NOT diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c index 7cf0a712ce..e7dd9d2bdb 100644 --- a/erts/emulator/drivers/unix/unix_efile.c +++ b/erts/emulator/drivers/unix/unix_efile.c @@ -1004,13 +1004,11 @@ efile_writev(Efile_error* errInfo, /* Where to return error codes */ * opened */ int fd, /* File descriptor to write to */ SysIOVec* iov, /* Vector of buffer structs. - * The structs are unchanged - * after the call */ - int iovcnt, /* Number of structs in vector */ - size_t size) /* Number of bytes to write */ + * The structs may be changed i.e. + * due to incomplete writes */ + int iovcnt) /* Number of structs in vector */ { int cnt = 0; /* Buffers so far written */ - int p = 0; /* Position in next buffer */ ASSERT(iovcnt >= 0); @@ -1021,66 +1019,47 @@ efile_writev(Efile_error* errInfo, /* Where to return error codes */ #endif while (cnt < iovcnt) { + if ((! iov[cnt].iov_base) || (iov[cnt].iov_len <= 0)) { + /* Empty buffer - skip */ + cnt++; + } else { /* Non-empty buffer */ + ssize_t w; /* Bytes written in this call */ #ifdef HAVE_WRITEV - int w; /* Bytes written in this call */ - int b = iovcnt - cnt; /* Buffers to write */ - if (b > MAXIOV) - b = MAXIOV; - if (iov[cnt].iov_base && iov[cnt].iov_len > 0) { - if (b == 1) { - /* Degenerated io vector */ - do { - w = write(fd, iov[cnt].iov_base + p, iov[cnt].iov_len - p); - } while (w < 0 && errno == EINTR); - } else { - /* Non-empty vector first. - * Adjust pos in first buffer in case of - * previous incomplete writev */ - iov[cnt].iov_base += p; - iov[cnt].iov_len -= p; + int b = iovcnt - cnt; /* Buffers to write */ + /* Use as many buffers as MAXIOV allows */ + if (b > MAXIOV) + b = MAXIOV; + if (b > 1) { do { w = writev(fd, &iov[cnt], b); } while (w < 0 && errno == EINTR); - iov[cnt].iov_base -= p; - iov[cnt].iov_len += p; - } - if (w < 0) - return check_error(-1, errInfo); - } else { - /* Empty vector first - skip */ - cnt++; - continue; - } - ASSERT(w >= 0); - /* Move forward to next vector to write */ - for (; cnt < iovcnt; cnt++) { - if (iov[cnt].iov_base && iov[cnt].iov_len > 0) { - if (w < iov[cnt].iov_len) - break; - else - w -= iov[cnt].iov_len; - } - } - ASSERT(w >= 0); - p = w > 0 ? w : 0; /* Skip p bytes next writev */ -#else /* #ifdef HAVE_WRITEV */ - if (iov[cnt].iov_base && iov[cnt].iov_len > 0) { - /* Non-empty vector */ - int w; /* Bytes written in this call */ - while (p < iov[cnt].iov_len) { - do { - w = write(fd, iov[cnt].iov_base + p, iov[cnt].iov_len - p); - } while (w < 0 && errno == EINTR); - if (w < 0) - return check_error(-1, errInfo); - p += w; + } else + /* Degenerated io vector - use regular write */ +#endif + { + do { + w = write(fd, iov[cnt].iov_base, iov[cnt].iov_len); + } while (w < 0 && errno == EINTR); + ASSERT(w <= iov[cnt].iov_len); + } + if (w < 0) return check_error(-1, errInfo); + /* Move forward to next buffer to write */ + for (; cnt < iovcnt && w > 0; cnt++) { + if (iov[cnt].iov_base && iov[cnt].iov_len > 0) { + if (w < iov[cnt].iov_len) { + /* Adjust the buffer for next write */ + iov[cnt].iov_len -= w; + iov[cnt].iov_base += w; + w = 0; + break; + } else { + w -= iov[cnt].iov_len; + } + } } - } - cnt++; - p = 0; -#endif /* #ifdef HAVE_WRITEV */ + ASSERT(w == 0); + } /* else Non-empty buffer */ } /* while (cnt< iovcnt) */ - size = 0; /* Avoid compiler warning */ return 1; } diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c index 0d3d334154..606fa1d7de 100644 --- a/erts/emulator/drivers/win32/win_efile.c +++ b/erts/emulator/drivers/win32/win_efile.c @@ -1115,8 +1115,7 @@ efile_writev(Efile_error* errInfo, /* Where to return error codes */ SysIOVec* iov, /* Vector of buffer structs. * The structs are unchanged * after the call */ - int iovcnt, /* Number of structs in vector */ - size_t size) /* Number of bytes to write */ + int iovcnt) /* Number of structs in vector */ { int cnt; /* Buffers so far written */ OVERLAPPED overlapped; diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c index cec22b3836..28e4382835 100644 --- a/erts/emulator/hipe/hipe_bif0.c +++ b/erts/emulator/hipe/hipe_bif0.c @@ -174,8 +174,13 @@ static inline unsigned char *bytearray_lvalue(Eterm bin, Eterm idx) { Sint i; unsigned char *bytes; +#ifndef DEBUG + ERTS_DECLARE_DUMMY(Uint bitoffs); + ERTS_DECLARE_DUMMY(Uint bitsize); +#else Uint bitoffs; Uint bitsize; +#endif if (is_not_binary(bin) || is_not_small(idx) || @@ -235,9 +240,15 @@ BIF_RETTYPE hipe_bifs_bitarray_2(BIF_ALIST_2) BIF_RETTYPE hipe_bifs_bitarray_update_3(BIF_ALIST_3) { unsigned char *bytes, bytemask; - Uint bitoffs, bitsize; Uint bitnr, bytenr; int set; +#ifndef DEBUG + ERTS_DECLARE_DUMMY(Uint bitoffs); + ERTS_DECLARE_DUMMY(Uint bitsize); +#else + Uint bitoffs; + Uint bitsize; +#endif if (is_not_binary(BIF_ARG_1)) BIF_ERROR(BIF_P, BADARG); @@ -267,8 +278,15 @@ BIF_RETTYPE hipe_bifs_bitarray_update_3(BIF_ALIST_3) BIF_RETTYPE hipe_bifs_bitarray_sub_2(BIF_ALIST_2) { unsigned char *bytes, bytemask; - Uint bitoffs, bitsize; Uint bitnr, bytenr; +#ifndef DEBUG + ERTS_DECLARE_DUMMY(Uint bitoffs); + ERTS_DECLARE_DUMMY(Uint bitsize); +#else + Uint bitoffs; + Uint bitsize; +#endif + if (is_not_binary(BIF_ARG_1)) BIF_ERROR(BIF_P, BADARG); @@ -397,10 +415,15 @@ BIF_RETTYPE hipe_bifs_enter_code_2(BIF_ALIST_2) Uint nrbytes; void *bytes; void *address; - Uint bitoffs; - Uint bitsize; Eterm trampolines; Eterm *hp; +#ifndef DEBUG + ERTS_DECLARE_DUMMY(Uint bitoffs); + ERTS_DECLARE_DUMMY(Uint bitsize); +#else + Uint bitoffs; + Uint bitsize; +#endif if (is_not_binary(BIF_ARG_1)) BIF_ERROR(BIF_P, BADARG); diff --git a/erts/emulator/hipe/hipe_gc.c b/erts/emulator/hipe/hipe_gc.c index 0199dea99e..e0575c35ff 100644 --- a/erts/emulator/hipe/hipe_gc.c +++ b/erts/emulator/hipe/hipe_gc.c @@ -46,9 +46,14 @@ Eterm *fullsweep_nstack(Process *p, Eterm *n_htop) char *src, *oh; Uint src_size, oh_size; + if (!p->hipe.nstack) { + ASSERT(!p->hipe.nsp && !p->hipe.nstend); + return n_htop; + } if (!nstack_walk_init_check(p)) return n_htop; + ASSERT(p->hipe.nsp && p->hipe.nstend); nsp = nstack_walk_nsp_begin(p); nsp_end = p->hipe.nstgraylim; if (nsp_end) @@ -136,9 +141,14 @@ void gensweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop) char *heap; Uint heap_size, mature_size; + if (!p->hipe.nstack) { + ASSERT(!p->hipe.nsp && !p->hipe.nstend); + return; + } if (!nstack_walk_init_check(p)) return; + ASSERT(p->hipe.nsp && p->hipe.nstend); nsp = nstack_walk_nsp_begin(p); nsp_end = p->hipe.nstgraylim; if (nsp_end) { diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index 370363bf9e..6bd7361612 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -859,7 +859,13 @@ resource_holder(Pid,Reply,List) -> threading(doc) -> ["Test the threading API functions (reuse tests from driver API)"]; -threading(Config) when is_list(Config) -> +threading(Config) when is_list(Config) -> + case erlang:system_info(threads) of + true -> threading_do(Config); + false -> {skipped,"No thread support"} + end. + +threading_do(Config) -> ?line Data = ?config(data_dir, Config), ?line File = filename:join(Data, "tester"), ?line {ok,tester,ModBin} = compile:file(File, [binary,return_errors]), diff --git a/erts/emulator/test/nif_SUITE_data/tester.c b/erts/emulator/test/nif_SUITE_data/tester.c index 08466d0f18..257b116322 100644 --- a/erts/emulator/test/nif_SUITE_data/tester.c +++ b/erts/emulator/test/nif_SUITE_data/tester.c @@ -61,6 +61,7 @@ static int reload(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) static ERL_NIF_TERM run(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { testcase_run(NULL); + testcase_cleanup(NULL); return enif_make_atom(env, "ok"); } diff --git a/erts/emulator/test/system_profile_SUITE.erl b/erts/emulator/test/system_profile_SUITE.erl index 32089e8872..659e43f81d 100644 --- a/erts/emulator/test/system_profile_SUITE.erl +++ b/erts/emulator/test/system_profile_SUITE.erl @@ -27,6 +27,7 @@ system_profile_on_and_off/1, runnable_procs/1, runnable_ports/1, + dont_profile_profiler/1, scheduler/1 ]). @@ -40,7 +41,7 @@ -define(default_timeout, ?t:minutes(1)). init_per_testcase(_Case, Config) -> - ?line Dog=?t:timetrap(?default_timeout), + Dog=?t:timetrap(?default_timeout), [{watchdog, Dog}|Config]. end_per_testcase(_Case, Config) -> Dog=?config(watchdog, Config), @@ -51,7 +52,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [system_profile_on_and_off, runnable_procs, - runnable_ports, scheduler]. + runnable_ports, scheduler, dont_profile_profiler]. groups() -> []. @@ -77,31 +78,31 @@ system_profile_on_and_off(suite) -> system_profile_on_and_off(doc) -> ["Tests switching system_profiling on and off."]; system_profile_on_and_off(Config) when is_list(Config) -> - ?line Pid = start_profiler_process(), + Pid = start_profiler_process(), % Test runnable_ports on and off - ?line undefined = erlang:system_profile(Pid, [runnable_ports]), - ?line {Pid, [runnable_ports]} = erlang:system_profile(), - ?line {Pid, [runnable_ports]} = erlang:system_profile(undefined, []), + undefined = erlang:system_profile(Pid, [runnable_ports]), + {Pid, [runnable_ports]} = erlang:system_profile(), + {Pid, [runnable_ports]} = erlang:system_profile(undefined, []), % Test runnable_procs on and off - ?line undefined = erlang:system_profile(Pid, [runnable_procs]), - ?line {Pid, [runnable_procs]} = erlang:system_profile(), - ?line {Pid, [runnable_procs]} = erlang:system_profile(undefined, []), + undefined = erlang:system_profile(Pid, [runnable_procs]), + {Pid, [runnable_procs]} = erlang:system_profile(), + {Pid, [runnable_procs]} = erlang:system_profile(undefined, []), % Test scheduler on and off - ?line undefined = erlang:system_profile(Pid, [scheduler]), - ?line {Pid, [scheduler]} = erlang:system_profile(), - ?line {Pid, [scheduler]} = erlang:system_profile(undefined, []), + undefined = erlang:system_profile(Pid, [scheduler]), + {Pid, [scheduler]} = erlang:system_profile(), + {Pid, [scheduler]} = erlang:system_profile(undefined, []), % Test combined runnable_ports, runnable_procs, scheduler; on and off - ?line undefined = erlang:system_profile(Pid, [scheduler, runnable_procs, runnable_ports]), - ?line {Pid, [scheduler,runnable_procs,runnable_ports]} = erlang:system_profile(), - ?line {Pid, [scheduler,runnable_procs,runnable_ports]} = erlang:system_profile(undefined, []), + undefined = erlang:system_profile(Pid, [scheduler, runnable_procs, runnable_ports]), + {Pid, [scheduler,runnable_procs,runnable_ports]} = erlang:system_profile(), + {Pid, [scheduler,runnable_procs,runnable_ports]} = erlang:system_profile(undefined, []), % Test turned off and kill process - ?line undefined = erlang:system_profile(), - ?line exit(Pid,kill), + undefined = erlang:system_profile(), + exit(Pid,kill), ok. %% Test runnable_procs @@ -111,25 +112,25 @@ runnable_procs(suite) -> runnable_procs(doc) -> ["Tests system_profiling with runnable_procs."]; runnable_procs(Config) when is_list(Config) -> - ?line Pid = start_profiler_process(), + Pid = start_profiler_process(), % start a ring of processes % FIXME: Set #laps and #nodes in config file Nodes = 10, Laps = 10, - ?line Master = ring(Nodes), - ?line undefined = erlang:system_profile(Pid, [runnable_procs]), + Master = ring(Nodes), + undefined = erlang:system_profile(Pid, [runnable_procs]), % loop a message - ?line ok = ring_message(Master, message, Laps), - ?line Events = get_profiler_events(), - ?line kill_em_all = kill_ring(Master), - ?line erlang:system_profile(undefined, []), + ok = ring_message(Master, message, Laps), + Events = get_profiler_events(), + kill_em_all = kill_ring(Master), + erlang:system_profile(undefined, []), put(master, Master), put(laps, Laps), - ?line true = has_runnable_event(Events), + true = has_runnable_event(Events), Pids = sort_events_by_pid(Events), - ?line ok = check_events(Pids), + ok = check_events(Pids), erase(), - ?line exit(Pid,kill), + exit(Pid,kill), ok. runnable_ports(suite) -> @@ -137,21 +138,21 @@ runnable_ports(suite) -> runnable_ports(doc) -> ["Tests system_profiling with runnable_port."]; runnable_ports(Config) when is_list(Config) -> - ?line Pid = start_profiler_process(), - ?line undefined = erlang:system_profile(Pid, [runnable_ports]), - ?line EchoPid = echo(Config), + Pid = start_profiler_process(), + undefined = erlang:system_profile(Pid, [runnable_ports]), + EchoPid = echo(Config), % FIXME: Set config to number_of_echos Laps = 10, put(laps, Laps), - ?line ok = echo_message(EchoPid, Laps, message), - ?line Events = get_profiler_events(), - ?line kill_em_all = kill_echo(EchoPid), - ?line erlang:system_profile(undefined, []), - ?line true = has_runnable_event(Events), + ok = echo_message(EchoPid, Laps, message), + Events = get_profiler_events(), + kill_em_all = kill_echo(EchoPid), + erlang:system_profile(undefined, []), + true = has_runnable_event(Events), Pids = sort_events_by_pid(Events), - ?line ok = check_events(Pids), + ok = check_events(Pids), erase(), - ?line exit(Pid,kill), + exit(Pid,kill), ok. scheduler(suite) -> @@ -160,46 +161,68 @@ scheduler(doc) -> ["Tests system_profiling with scheduler."]; scheduler(Config) when is_list(Config) -> case {erlang:system_info(smp_support), erlang:system_info(schedulers_online)} of - {false,_} -> ?line {skipped, "No need for scheduler test when smp support is disabled."}; - {_, 1} -> ?line {skipped, "No need for scheduler test when only one scheduler online."}; + {false,_} -> {skipped, "No need for scheduler test when smp support is disabled."}; + {_, 1} -> {skipped, "No need for scheduler test when only one scheduler online."}; _ -> Nodes = 10, - ?line ok = check_block_system(Nodes), - ?line ok = check_multi_scheduling_block(Nodes), - ok + ok = check_block_system(Nodes), + ok = check_multi_scheduling_block(Nodes) end. +% the profiler pid should not be profiled +dont_profile_profiler(suite) -> + []; +dont_profile_profiler(doc) -> + ["Ensure system profiler process is not profiled."]; +dont_profile_profiler(Config) when is_list(Config) -> + Pid = start_profiler_process(), + + Nodes = 10, + Laps = 10, + Master = ring(Nodes), + undefined = erlang:system_profile(Pid, [runnable_procs]), + % loop a message + ok = ring_message(Master, message, Laps), + erlang:system_profile(undefined, []), + kill_em_all = kill_ring(Master), + Events = get_profiler_events(), + false = has_profiler_pid_event(Events, Pid), + + exit(Pid,kill), + ok. + + %%% Check scheduler profiling check_multi_scheduling_block(Nodes) -> - ?line Pid = start_profiler_process(), - ?line undefined = erlang:system_profile(Pid, [scheduler]), - ?line {ok, Supervisor} = start_load(Nodes), - ?line erlang:system_flag(multi_scheduling, block), - ?line erlang:system_flag(multi_scheduling, unblock), - ?line {Pid, [scheduler]} = erlang:system_profile(undefined, []), - ?line Events = get_profiler_events(), - ?line true = has_scheduler_event(Events), + Pid = start_profiler_process(), + undefined = erlang:system_profile(Pid, [scheduler]), + {ok, Supervisor} = start_load(Nodes), + erlang:system_flag(multi_scheduling, block), + erlang:system_flag(multi_scheduling, unblock), + {Pid, [scheduler]} = erlang:system_profile(undefined, []), + Events = get_profiler_events(), + true = has_scheduler_event(Events), stop_load(Supervisor), - ?line exit(Pid,kill), + exit(Pid,kill), erase(), ok. check_block_system(Nodes) -> - ?line Dummy = spawn(?MODULE, profiler_process, [[]]), - ?line Pid = start_profiler_process(), - ?line undefined = erlang:system_profile(Pid, [scheduler]), - ?line {ok, Supervisor} = start_load(Nodes), + Dummy = spawn(?MODULE, profiler_process, [[]]), + Pid = start_profiler_process(), + undefined = erlang:system_profile(Pid, [scheduler]), + {ok, Supervisor} = start_load(Nodes), % FIXME: remove wait !! wait(300), - ?line undefined = erlang:system_monitor(Dummy, [busy_port]), - ?line {Dummy, [busy_port]} = erlang:system_monitor(undefined, []), - ?line {Pid, [scheduler]} = erlang:system_profile(undefined, []), - ?line Events = get_profiler_events(), - ?line true = has_scheduler_event(Events), + undefined = erlang:system_monitor(Dummy, [busy_port]), + {Dummy, [busy_port]} = erlang:system_monitor(undefined, []), + {Pid, [scheduler]} = erlang:system_profile(undefined, []), + Events = get_profiler_events(), + true = has_scheduler_event(Events), stop_load(Supervisor), - ?line exit(Pid,kill), - ?line exit(Dummy,kill), + exit(Pid,kill), + exit(Dummy,kill), erase(), ok. @@ -211,17 +234,17 @@ check_events([Pid | Pids]) -> Laps = get(laps), CheckPids = get(pids), {Events, N} = get_pid_events(Pid), - ?line ok = check_event_flow(Events), - ?line ok = check_event_ts(Events), + ok = check_event_flow(Events), + ok = check_event_ts(Events), IsMember = lists:member(Pid, CheckPids), case Pid of Master -> io:format("Expected ~p and got ~p profile events from ~p: ok~n", [Laps*2+2, N, Pid]), - ?line N = Laps*2 + 2, + N = Laps*2 + 2, check_events(Pids); Pid when IsMember == true -> io:format("Expected ~p and got ~p profile events from ~p: ok~n", [Laps*2, N, Pid]), - ?line N = Laps*2, + N = Laps*2, check_events(Pids); Pid -> check_events(Pids) @@ -448,6 +471,12 @@ has_runnable_event(Events) -> end end, Events). +has_profiler_pid_event([], _) -> false; +has_profiler_pid_event([{profile, Pid, _Activity, _MFA, _TS}|Events], Pid) -> true; +has_profiler_pid_event([_|Events], Pid) -> + has_profiler_pid_event(Events, Pid). + + wait(Time) -> receive after Time -> ok end. %%% diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c index 7a5746e630..fae4d870cc 100644 --- a/erts/etc/common/heart.c +++ b/erts/etc/common/heart.c @@ -685,14 +685,16 @@ do_terminate(reason) print_error("Would reboot. Terminating."); else { kill_old_erlang(); - system(command); + /* suppress gcc warning with 'if' */ + if(system(command)); print_error("Executed \"%s\". Terminating.",command); } free_env_val(command); } else { kill_old_erlang(); - system((char*)&cmd[0]); + /* suppress gcc warning with 'if' */ + if(system((char*)&cmd[0])); print_error("Executed \"%s\". Terminating.",cmd); } } diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c index 77bfd5e2bc..d25d2910b4 100644 --- a/erts/etc/common/inet_gethost.c +++ b/erts/etc/common/inet_gethost.c @@ -1141,14 +1141,12 @@ static Worker *pick_worker(void) static Worker *pick_worker_greedy(AddrByte *domainbuff) { int i; - int ql = 0; int found = -1; for (i=0; i < num_busy_workers; ++i) { if (domaineq(busy_workers[i].domain, domainbuff)) { if ((found < 0) || (busy_workers[i].que_size < busy_workers[found].que_size)) { found = i; - ql = busy_workers[i].que_size; } } } @@ -1945,12 +1943,14 @@ static int worker_loop(void) } m = NULL; #else - write(1, reply, data_size); /* No signals expected */ + /* expect no signals */ + if (write(1, reply, data_size) < 0) + goto fail; #endif } /* for (;;) */ -#ifdef WIN32 fail: +#ifdef WIN32 if (m != NULL) { FREE(m); } @@ -1959,8 +1959,8 @@ static int worker_loop(void) if (reply) { FREE(reply); } - return 1; #endif + return 1; } static int map_netdb_error(int netdb_code) @@ -2561,7 +2561,8 @@ static void debugf(char *format, ...) WriteFile(debug_console_allocated,buff,strlen(buff),&res,NULL); } #else - write(2,buff,strlen(buff)); + /* suppress warning with 'if' */ + if(write(2,buff,strlen(buff))); #endif va_end(ap); } @@ -2583,7 +2584,8 @@ static void warning(char *format, ...) WriteFile(GetStdHandle(STD_ERROR_HANDLE),buff,strlen(buff),&res,NULL); } #else - write(2,buff,strlen(buff)); + /* suppress warning with 'if' */ + if(write(2,buff,strlen(buff))); #endif va_end(ap); } @@ -2605,7 +2607,8 @@ static void fatal(char *format, ...) WriteFile(GetStdHandle(STD_ERROR_HANDLE),buff,strlen(buff),&res,NULL); } #else - write(2,buff,strlen(buff)); + /* suppress warning with 'if' */ + if(write(2,buff,strlen(buff))); #endif va_end(ap); #ifndef WIN32 diff --git a/erts/etc/unix/to_erl.c b/erts/etc/unix/to_erl.c index 11fa3ff4cc..67274e67ed 100644 --- a/erts/etc/unix/to_erl.c +++ b/erts/etc/unix/to_erl.c @@ -352,7 +352,10 @@ int main(int argc, char **argv) * to trigger the version handshaking between to_erl and run_erl * at the start of every new to_erl-session. */ - write(wfd, "\022", 1); + + if (write(wfd, "\022", 1) < 0) { + fprintf(stderr, "Error in writing ^R to FIFO.\n"); + } /* * read and write @@ -412,7 +415,7 @@ int main(int argc, char **argv) if (len) { #ifdef DEBUG - write(1, buf, len); + if(write(1, buf, len)); #endif if (write_all(wfd, buf, len) != len) { fprintf(stderr, "Error in writing to FIFO.\n"); diff --git a/erts/test/erl_print_SUITE.erl b/erts/test/erl_print_SUITE.erl index ee1a200530..adc353bd51 100644 --- a/erts/test/erl_print_SUITE.erl +++ b/erts/test/erl_print_SUITE.erl @@ -303,7 +303,7 @@ read_case_data(Port, TestCase) -> {Port, {data, {eol, [?PID_MARKER | PidStr]}}} -> ?line ?t:format("Port program pid: ~s~n", [PidStr]), ?line CaseProc = self(), - ?line list_to_integer(PidStr), % Sanity check + ?line _ = list_to_integer(PidStr), % Sanity check spawn_opt(fun () -> port_prog_killer(CaseProc, PidStr) end, diff --git a/erts/test/ethread_SUITE.erl b/erts/test/ethread_SUITE.erl index 80f988b0aa..5bb5aed3ed 100644 --- a/erts/test/ethread_SUITE.erl +++ b/erts/test/ethread_SUITE.erl @@ -68,9 +68,6 @@ tests() -> atomic, dw_atomic_massage]. -all(doc) -> []; -all(suite) -> tests(). - suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> @@ -125,35 +122,37 @@ try_lock_mutex(suite) -> try_lock_mutex(Config) -> run_case(Config, "try_lock_mutex", ""). -wd_dispatch(P) -> - receive - bye -> - ?line true = port_command(P, "-1 "), - ?line bye; - L when is_list(L) -> - ?line true = port_command(P, L), - ?line wd_dispatch(P) - end. - -watchdog(Port) -> - ?line process_flag(priority, max), - ?line receive after 500 -> ok end, - - ?line random:seed(), - ?line true = port_command(Port, "0 "), - ?line lists:foreach(fun (T) -> - erlang:send_after(T, - self(), - integer_to_list(T) - ++ " ") - end, - lists:usort(lists:map(fun (_) -> - random:uniform(4500)+500 - end, - lists:duplicate(50,0)))), - ?line erlang:send_after(5100, self(), bye), - - wd_dispatch(Port). +%% Remove dead code? + +% wd_dispatch(P) -> +% receive +% bye -> +% ?line true = port_command(P, "-1 "), +% ?line bye; +% L when is_list(L) -> +% ?line true = port_command(P, L), +% ?line wd_dispatch(P) +% end. +% +% watchdog(Port) -> +% ?line process_flag(priority, max), +% ?line receive after 500 -> ok end, +% +% ?line random:seed(), +% ?line true = port_command(Port, "0 "), +% ?line lists:foreach(fun (T) -> +% erlang:send_after(T, +% self(), +% integer_to_list(T) +% ++ " ") +% end, +% lists:usort(lists:map(fun (_) -> +% random:uniform(4500)+500 +% end, +% lists:duplicate(50,0)))), +% ?line erlang:send_after(5100, self(), bye), +% +% wd_dispatch(Port). cond_wait(doc) -> ["Tests ethr_cond_wait with ethr_cond_signal and ethr_cond_broadcast."]; @@ -307,7 +306,7 @@ read_case_data(Port, TestCase) -> {Port, {data, {eol, [?PID_MARKER | PidStr]}}} -> ?line ?t:format("Port program pid: ~s~n", [PidStr]), ?line CaseProc = self(), - ?line list_to_integer(PidStr), % Sanity check + ?line _ = list_to_integer(PidStr), % Sanity check spawn_opt(fun () -> port_prog_killer(CaseProc, PidStr) end, diff --git a/erts/test/z_SUITE.erl b/erts/test/z_SUITE.erl index 482ecb8fba..28da923497 100644 --- a/erts/test/z_SUITE.erl +++ b/erts/test/z_SUITE.erl @@ -236,8 +236,8 @@ format_core(#core_search_conf{file = false}, Core, Ignore) -> [Ignore, Core] ++ mod_time_list(Core)); format_core(#core_search_conf{file = File}, Core, Ignore) -> FRes = str_strip(os:cmd(File ++ " " ++ Core)), - case catch regexp:match(FRes, Core) of - {match, _, _} -> + case catch re:run(FRes, Core, [caseless,{capture,none}]) of + match -> io:format(" ~s~s " ++ time_fstr() ++ "~n", [Ignore, FRes] ++ mod_time_list(Core)); _ -> |