On Wed, May 24, 2023 at 8:31 PM Ilya Maximets <[email protected]> wrote:
> On 5/19/23 09:36, Ales Musil wrote: > > Use the backtrace functions that is provided by libc, > > this allows us to get backtrace that is independent of > > the current memory map of the process. Which in turn can > > be used for debugging/tracing purpose. The backtrace > > is not 100% accurate due to various optimizations, most > > notably "-fomit-frame-pointer" and LTO. This might result > > that the line in source file doesn't correspond to the > > real line. However, it should be able to pinpoint at least > > the function where the backtrace was called. > > > > The usage for SIGSEGV is determined during compilation > > based on available libraries. Libunwind has higher priority > > if both methods are available to keep the compatibility with > > current behavior. > > > > The backtrace is not marked as signal safe however the backtrace > > manual page gives more detailed explanation why it might be the > > case [0]. Load the "libgcc" or equivalent in advance within the > > "fatal_signal_init" which should ensure that subsequent calls > > to backtrace* do not call malloc and are signal safe. > > > > The typical backtrace will look similar to the one below: > > /lib64/libopenvswitch-3.1.so.0(backtrace_capture+0x1e) [0x7fc5db298dfe] > > /lib64/libopenvswitch-3.1.so.0(log_backtrace_at+0x57) [0x7fc5db2999e7] > > /lib64/libovsdb-3.1.so.0(ovsdb_txn_complete+0x7b) [0x7fc5db56247b] > > /lib64/libovsdb-3.1.so.0(ovsdb_txn_propose_commit_block+0x8d) > [0x7fc5db563a8d] > > ovsdb-server(+0xa661) [0x562cfce2e661] > > ovsdb-server(+0x7e39) [0x562cfce2be39] > > /lib64/libc.so.6(+0x27b4a) [0x7fc5db048b4a] > > /lib64/libc.so.6(__libc_start_main+0x8b) [0x7fc5db048c0b] > > ovsdb-server(+0x8c35) [0x562cfce2cc35] > > > > backtrace.h elaborates on how to effectively get the line > > information associated with the addressed presented in the > > backtrace. > > > > [0] > > backtrace() and backtrace_symbols_fd() don't call malloc() > > explicitly, but they are part of libgcc, which gets loaded > > dynamically when first used. Dynamic loading usually triggers > > a call to malloc(3). If you need certain calls to these two > > functions to not allocate memory (in signal handlers, for > > example), you need to make sure libgcc is loaded beforehand > > > > Reported-at: https://bugzilla.redhat.com/2177760 > > Signed-off-by: Ales Musil <[email protected]> > > --- > > v2: Extend the current use of libunwind rather than replacing it. > > v3: Allow vlog_fd to be also 0. > > Return the backtrace log from monitor in updated form. > > Return use of the "vlog_direct_write_to_log_file_unsafe". > > v4: Rebase on top of current master. > > Address comments from Ilya: > > Address the coding style issues. > > Make sure that the backrace received by monitor doesn't > > have more than maximum allowed frames. > > Change the backtrace_format to accept delimiter. > > Remove unnecessary checks in the tests. > > --- > > Hi, Ales. See a few comments below. > Hi Ilya, sorry I have missed those in previous email, not sure why. It should be addressed in v5. > > include/openvswitch/vlog.h | 3 + > > lib/backtrace.c | 116 +++++++++++++++++++++++++------------ > > lib/backtrace.h | 57 +++++++++++------- > > lib/fatal-signal.c | 52 +++++++++++++++-- > > lib/ovsdb-error.c | 15 ++--- > > lib/vlog.c | 7 +++ > > m4/openvswitch.m4 | 9 ++- > > tests/atlocal.in | 2 + > > tests/daemon.at | 45 ++++++++++++++ > > 9 files changed, 228 insertions(+), 78 deletions(-) > > > > diff --git a/include/openvswitch/vlog.h b/include/openvswitch/vlog.h > > index e53ce6d81..d3c369bf2 100644 > > --- a/include/openvswitch/vlog.h > > +++ b/include/openvswitch/vlog.h > > @@ -148,6 +148,9 @@ void vlog_set_syslog_target(const char *target); > > /* Write directly to log file. */ > > void vlog_direct_write_to_log_file_unsafe(const char *s); > > > > +/* Return the current vlog file descriptor. */ > > +int vlog_fd(void); > > I'll repeat my comment from v3 here: > """ > It's unfortunate we need to export this kind of function. We should > give it a better name at least. Maybe vlog_get_log_file_fd_unsafe() ? > vlog module doesn't have a file descriptor, file does. And fd is > supposed to be protected by a mutex that we're clearly not holding > while using this function, so 'unsafe'. > """ > > > + > > /* Initialization. */ > > void vlog_init(void); > > void vlog_enable_async(void); > > diff --git a/lib/backtrace.c b/lib/backtrace.c > > index 2853d5ff1..4cac5e14c 100644 > > --- a/lib/backtrace.c > > +++ b/lib/backtrace.c > > @@ -32,12 +32,27 @@ VLOG_DEFINE_THIS_MODULE(backtrace); > > void > > backtrace_capture(struct backtrace *b) > > { > > - void *frames[BACKTRACE_MAX_FRAMES]; > > - int i; > > + b->n_frames = backtrace(b->frames, BACKTRACE_MAX_FRAMES); > > +} > > + > > +void > > +backtrace_format(const struct backtrace *bt, struct ds *ds, > > + const char *delimiter) > > +{ > > + if (bt->n_frames) { > > + char **symbols = backtrace_symbols(bt->frames, bt->n_frames); > > + > > + if (!symbols) { > > + return; > > + } > > > > - b->n_frames = backtrace(frames, BACKTRACE_MAX_FRAMES); > > - for (i = 0; i < b->n_frames; i++) { > > - b->frames[i] = (uintptr_t) frames[i]; > > + for (int i = 0; i < bt->n_frames - 1; i++) { > > + ds_put_format(ds, "%s%s", symbols[i], delimiter); > > + } > > + > > + ds_put_format(ds, "%s", symbols[bt->n_frames - 1]); > > + > > + free(symbols); > > } > > } > > > > @@ -47,23 +62,14 @@ backtrace_capture(struct backtrace *backtrace) > > { > > backtrace->n_frames = 0; > > } > > -#endif > > > > -static char * > > -backtrace_format(const struct backtrace *b, struct ds *ds) > > +void > > +backtrace_format(const struct backtrace *bt OVS_UNUSED, struct ds *ds, > > + const char *delimiter OVS_UNUSED) > > { > > - if (b->n_frames) { > > - int i; > > - > > - ds_put_cstr(ds, " (backtrace:"); > > - for (i = 0; i < b->n_frames; i++) { > > - ds_put_format(ds, " 0x%08"PRIxPTR, b->frames[i]); > > - } > > - ds_put_cstr(ds, ")"); > > - } > > - > > - return ds_cstr(ds); > > + ds_put_cstr(ds, "backtrace() is not supported!\n"); > > } > > +#endif > > > > void > > log_backtrace_at(const char *msg, const char *where) > > @@ -77,41 +83,75 @@ log_backtrace_at(const char *msg, const char *where) > > } > > > > ds_put_cstr(&ds, where); > > - VLOG_ERR("%s", backtrace_format(&b, &ds)); > > + ds_put_cstr(&ds, " backtrace:\n"); > > + backtrace_format(&b, &ds, "\n"); > > + VLOG_ERR("%s", ds_cstr_ro(&ds)); > > > > ds_destroy(&ds); > > } > > > > +static bool > > +read_received_backtrace(int fd, void *dest, size_t len) > > +{ > > + VLOG_WARN("%s fd %d", __func__, fd); > > + fcntl(fd, F_SETFL, O_NONBLOCK); > > + memset(dest, 0, len); > > + > > + int byte_read = read(fd, dest, len); > > + if (byte_read < 0) { > > + VLOG_ERR("Read fd %d failed: %s", fd, ovs_strerror(errno)); > > + return false; > > + } > > + return true; > > +} > > + > > #ifdef HAVE_UNWIND > > void > > -log_received_backtrace(int fd) { > > - int byte_read; > > +log_received_backtrace(int fd) > > +{ > > struct unw_backtrace backtrace[UNW_MAX_DEPTH]; > > > > - VLOG_WARN("%s fd %d", __func__, fd); > > - fcntl(fd, F_SETFL, O_NONBLOCK); > > - memset(backtrace, 0, UNW_MAX_BUF); > > + if (read_received_backtrace(fd, backtrace, UNW_MAX_BUF)) { > > + struct ds ds = DS_EMPTY_INITIALIZER; > > + > > + ds_put_cstr(&ds, BACKTRACE_DUMP_MSG); > > > > - byte_read = read(fd, backtrace, UNW_MAX_BUF); > > - if (byte_read < 0) { > > - VLOG_ERR("Read fd %d failed: %s", fd, > > - ovs_strerror(errno)); > > - } else if (byte_read > 0) { > > - VLOG_WARN("SIGSEGV detected, backtrace:"); > > for (int i = 0; i < UNW_MAX_DEPTH; i++) { > > if (backtrace[i].func[0] == 0) { > > break; > > } > > - VLOG_WARN("0x%016"PRIxPTR" <%s+0x%"PRIxPTR">\n", > > - backtrace[i].ip, > > - backtrace[i].func, > > - backtrace[i].offset); > > + ds_put_format(&ds, "0x%016"PRIxPTR" <%s+0x%"PRIxPTR">\n", > > + backtrace[i].ip, > > + backtrace[i].func, > > + backtrace[i].offset); > > } > > + > > + VLOG_WARN("%s", ds_cstr_ro(&ds)); > > + > > + ds_destroy(&ds); > > } > > } > > -#else /* !HAVE_UNWIND */ > > +#elif HAVE_BACKTRACE > > +void > > +log_received_backtrace(int fd) > > +{ > > + struct backtrace bt; > > + > > + if (read_received_backtrace(fd, &bt, sizeof bt)) { > > + struct ds ds = DS_EMPTY_INITIALIZER; > > + > > + bt.n_frames = MIN(bt.n_frames, BACKTRACE_MAX_FRAMES); > > + > > + ds_put_cstr(&ds, BACKTRACE_DUMP_MSG); > > + backtrace_format(&bt, &ds, "\n"); > > + VLOG_WARN("%s", ds_cstr_ro(&ds)); > > + > > + ds_destroy(&ds); > > + } > > +} > > +#else > > void > > log_received_backtrace(int daemonize_fd OVS_UNUSED) { > > - VLOG_WARN("Backtrace using libunwind not supported."); > > + VLOG_WARN("Backtrace using libunwind or backtrace() is not > supported."); > > } > > -#endif /* HAVE_UNWIND */ > > +#endif > > diff --git a/lib/backtrace.h b/lib/backtrace.h > > index 5708bf9c6..50e9c2f79 100644 > > --- a/lib/backtrace.h > > +++ b/lib/backtrace.h > > @@ -36,41 +36,53 @@ > > * log_backtrace_msg("your message"); <-- with a message > > * > > * > > - * A typical log will look like the following. The hex numbers listed > after > > - * "backtrace" are the addresses of the backtrace. > > + * A typical backtrace will look like the following example: > > + * /lib64/libopenvswitch-3.1.so.0(backtrace_capture+0x1e) > [0x7fc5db298dfe] > > + * /lib64/libopenvswitch-3.1.so.0(log_backtrace_at+0x57) > [0x7fc5db2999e7] > > + * /lib64/libovsdb-3.1.so.0(ovsdb_txn_complete+0x7b) [0x7fc5db56247b] > > + * /lib64/libovsdb-3.1.so.0(ovsdb_txn_propose_commit_block+0x8d) > > + * [0x7fc5db563a8d] > > + * ovsdb-server(+0xa661) [0x562cfce2e661] > > + * ovsdb-server(+0x7e39) [0x562cfce2be39] > > + * /lib64/libc.so.6(+0x27b4a) [0x7fc5db048b4a] > > + * /lib64/libc.so.6(__libc_start_main+0x8b) [0x7fc5db048c0b] > > + * ovsdb-server(+0x8c35) [0x562cfce2cc35] > > * > > - * > 2014-03-13T23:18:11.979Z|00002|backtrace(revalidator_6)|ERR|lib/dpif-netdev.c:1312: > (backtrace: 0x00521f57 0x00460365 0x00463ea4 0x0046470b 0x0043b32d > 0x0043bac3 0x0043bae2 0x0043943b 0x004c22b3 0x2b5b3ac94e9a 0x2b5b3b4a33fd) > > + * GDB can be used to view the exact line of the code for particular > backtrace. > > + * One thing to keep in mind is that the lines in source files might not > > + * 100% correspond with the backtrace due to various optimizations as > LTO etc. > > + * (The effect can be seen in this example). > > * > > - * The following bash command can be used to view backtrace in > > - * a more readable form. > > - * addr2line -p -e vswitchd/ovs-vswitchd <cut-and-paste back traces> > > + * Assuming that debuginfo for the library or binary is installed load > it to > > + * GDB: > > + * $ gdb ovsdb-server > > + * (gdb) list *(+0x7e39) > > + * 0x7e39 is in main (ovsdb/ovsdb-server.c:278). > > + * (gdb) list *(+0xa661) > > + * 0xa661 is in commit_txn (ovsdb/ovsdb-server.c:1173) > > * > > - * An typical run and output will look like: > > - * addr2line -p -e vswitchd/ovs-vswitchd 0x00521f57 0x00460365 > 0x00463ea4 > > - * 0x0046470b 0x0043b32d 0x0043bac3 0x0043bae2 0x0043943b 0x004c22b3 > > - * 0x2b5b3ac94e9a 0x2b5b3b4a33fd > > + * $ gdb /lib64/libovsdb-3.1.so.0 > > + * (gdb) list *(ovsdb_txn_propose_commit_block+0x8d) > > + * 0x3aa8d is in ovsdb_txn_propose_commit_block > (ovsdb/transaction.c:1328) > > + * (gdb) list *(ovsdb_txn_complete+0x7b) > > + * 0x3947b is in ovsdb_txn_complete (./include/openvswitch/list.h:321) > > * > > - * openvswitch/lib/backtrace.c:33 > > - * openvswitch/lib/dpif-netdev.c:1312 > > - * openvswitch/lib/dpif.c:937 > > - * openvswitch/lib/dpif.c:1258 > > - * openvswitch/ofproto/ofproto-dpif-upcall.c:1440 > > - * openvswitch/ofproto/ofproto-dpif-upcall.c:1595 > > - * openvswitch/ofproto/ofproto-dpif-upcall.c:160 > > - * openvswitch/ofproto/ofproto-dpif-upcall.c:717 > > - * openvswitch/lib/ovs-thread.c:268 > > - * ??:0 > > - * ??:0 > > + * $ gdb /lib64/libopenvswitch-3.1.so.0 > > + * (gdb) list *(log_backtrace_at+0x57) > > + * 0x999e7 is in log_backtrace_at (lib/backtrace.c:77) > > + * (gdb) list *(backtrace_capture+0x1e) > > + * 0x98dfe is in backtrace_capture (lib/backtrace.c:35) > > */ > > > > #define log_backtrace() log_backtrace_at(NULL, OVS_SOURCE_LOCATOR); > > #define log_backtrace_msg(msg) log_backtrace_at(msg, > OVS_SOURCE_LOCATOR); > > > > #define BACKTRACE_MAX_FRAMES 31 > > +#define BACKTRACE_DUMP_MSG "SIGSEGV detected, backtrace:\n" > > > > struct backtrace { > > int n_frames; > > - uintptr_t frames[BACKTRACE_MAX_FRAMES]; > > + void *frames[BACKTRACE_MAX_FRAMES]; > > }; > > > > #ifdef HAVE_UNWIND > > @@ -88,6 +100,7 @@ struct unw_backtrace { > > > > void backtrace_capture(struct backtrace *); > > void log_backtrace_at(const char *msg, const char *where); > > +void backtrace_format(const struct backtrace *, struct ds *, const char > *); > > void log_received_backtrace(int fd); > > > > #endif /* backtrace.h */ > > diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c > > index bbb31ef27..b5d1f7662 100644 > > --- a/lib/fatal-signal.c > > +++ b/lib/fatal-signal.c > > @@ -35,10 +35,14 @@ > > > > #include "openvswitch/type-props.h" > > > > -#ifdef HAVE_UNWIND > > +#if defined(HAVE_UNWIND) || defined(HAVE_BACKTRACE) > > #include "daemon-private.h" > > #endif > > > > +#ifdef HAVE_BACKTRACE > > +#include <execinfo.h> > > +#endif > > + > > #ifndef SIG_ATOMIC_MAX > > #define SIG_ATOMIC_MAX TYPE_MAXIMUM(sig_atomic_t) > > #endif > > @@ -94,6 +98,17 @@ fatal_signal_init(void) > > inited = true; > > > > ovs_mutex_init_recursive(&mutex); > > + > > + /* The dummy backtrace is needed. > > + * See comment for send_backtrace_to_monitor(). */ > > + struct backtrace dummy_bt; > > + > > + backtrace_capture(&dummy_bt); > > + > > + if (!dummy_bt.n_frames) { > > + VLOG_DBG("Capturing of dummy backtrace has failed."); > > + } > > + > > #ifndef _WIN32 > > xpipe_nonblocking(signal_fds); > > #else > > @@ -181,7 +196,8 @@ llong_to_hex_str(unsigned long long value, char *str) > > * library functions used here must be async-signal-safe. > > */ > > static inline void > > -send_backtrace_to_monitor(void) { > > +send_backtrace_to_monitor(void) > > +{ > > /* volatile added to prevent a "clobbered" error on ppc64le with > gcc */ > > volatile int dep; > > struct unw_backtrace unw_bt[UNW_MAX_DEPTH]; > > @@ -211,11 +227,10 @@ send_backtrace_to_monitor(void) { > > /* Since there is no monitor daemon running, write backtrace > > * in current process. > > */ > > - char str[] = "SIGSEGV detected, backtrace:\n"; > > char ip_str[16], offset_str[6]; > > char line[64], fn_name[UNW_MAX_FUNCN]; > > > > - vlog_direct_write_to_log_file_unsafe(str); > > + vlog_direct_write_to_log_file_unsafe(BACKTRACE_DUMP_MSG); > > > > for (int i = 0; i < dep; i++) { > > memset(line, 0, sizeof line); > > @@ -239,6 +254,35 @@ send_backtrace_to_monitor(void) { > > } > > } > > } > > +#elif HAVE_BACKTRACE > > +/* Send the backtrace to monitor thread. > > + * > > + * Note that this runs in the signal handling context, any system > > + * library functions used here must be async-signal-safe. > > + * backtrace() is only signal safe if the "libgcc" or equivalent was > loaded > > + * before the signal handler. In order to keep it safe the > fatal_signal_init() > > + * should always call backtrace_capture which will ensure that "libgcc" > or > > + * equivlent is loaded. > > + */ > > +static inline void > > +send_backtrace_to_monitor(void) > > +{ > > + struct backtrace bt; > > + > > + backtrace_capture(&bt); > > + > > + if (monitor && daemonize_fd > -1) { > > + ignore(write(daemonize_fd, &bt, sizeof(bt))); > > Same here: > """ > Don't parethesize the argument of sizeof. > """ > > > + } else { > > + int log_fd = vlog_fd(); > > + if (log_fd < 0) { > > + return; > > + } > > + > > + vlog_direct_write_to_log_file_unsafe(BACKTRACE_DUMP_MSG); > > + backtrace_symbols_fd(bt.frames, bt.n_frames, log_fd); > > + } > > +} > > #else > > static inline void > > send_backtrace_to_monitor(void) { > > diff --git a/lib/ovsdb-error.c b/lib/ovsdb-error.c > > index a75ad36b7..ece88f940 100644 > > --- a/lib/ovsdb-error.c > > +++ b/lib/ovsdb-error.c > > @@ -139,17 +139,6 @@ ovsdb_internal_error(struct ovsdb_error > *inner_error, > > va_end(args); > > } > > > > - backtrace_capture(&backtrace); > > - if (backtrace.n_frames) { > > - int i; > > - > > - ds_put_cstr(&ds, " (backtrace:"); > > - for (i = 0; i < backtrace.n_frames; i++) { > > - ds_put_format(&ds, " 0x%08"PRIxPTR, backtrace.frames[i]); > > - } > > - ds_put_char(&ds, ')'); > > - } > > - > > ds_put_format(&ds, " (%s %s)", program_name, VERSION); > > > > if (inner_error) { > > @@ -158,6 +147,10 @@ ovsdb_internal_error(struct ovsdb_error > *inner_error, > > free(s); > > } > > > > + ds_put_cstr(&ds, ", backtrace:"); > > + backtrace_capture(&backtrace); > > + backtrace_format(&backtrace, &ds, ", "); > > What is the point of miving this part to the end of the message? > And we should keep it parenthesized to keep the previous format. > > > + > > error = ovsdb_error("internal error", "%s", ds_cstr(&ds)); > > > > ds_destroy(&ds); > > diff --git a/lib/vlog.c b/lib/vlog.c > > index 9ddea48b8..c0fa29890 100644 > > --- a/lib/vlog.c > > +++ b/lib/vlog.c > > @@ -664,6 +664,13 @@ vlog_direct_write_to_log_file_unsafe(const char *s) > > } > > } > > > > +int > > +vlog_fd(void) > > + OVS_NO_THREAD_SAFETY_ANALYSIS > > +{ > > + return log_fd; > > +} > > + > > /* Returns 'false' if 'facility' is not a valid string. If 'facility' > > * is a valid string, sets 'value' with the integer value of 'facility' > > * and returns 'true'. */ > > diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4 > > index 14d9249b8..f4943b140 100644 > > --- a/m4/openvswitch.m4 > > +++ b/m4/openvswitch.m4 > > @@ -359,9 +359,12 @@ AC_DEFUN([OVS_CHECK_DBDIR], > > > > dnl Defines HAVE_BACKTRACE if backtrace() is found. > > AC_DEFUN([OVS_CHECK_BACKTRACE], > > - [AC_SEARCH_LIBS([backtrace], [execinfo ubacktrace], > > - [AC_DEFINE([HAVE_BACKTRACE], [1], > > - [Define to 1 if you have > backtrace(3).])])]) > > + [AC_SEARCH_LIBS([backtrace], [execinfo ubacktrace], > [HAVE_BACKTRACE=yes], [HAVE_BACKTRACE=no]) > > + if test "$HAVE_BACKTRACE" = "yes"; then > > + AC_DEFINE([HAVE_BACKTRACE], [1], [Define to 1 if you have > backtrace(3).]) > > + fi > > + AM_CONDITIONAL([HAVE_BACKTRACE], [test "$HAVE_BACKTRACE" = "yes"]) > > + AC_SUBST([HAVE_BACKTRACE])]) > > > > dnl Defines HAVE_PERF_EVENT if linux/perf_event.h is found. > > AC_DEFUN([OVS_CHECK_PERF_EVENT], > > diff --git a/tests/atlocal.in b/tests/atlocal.in > > index 859668586..18d5efae0 100644 > > --- a/tests/atlocal.in > > +++ b/tests/atlocal.in > > @@ -2,6 +2,8 @@ > > HAVE_OPENSSL='@HAVE_OPENSSL@' > > OPENSSL_SUPPORTS_SNI='@OPENSSL_SUPPORTS_SNI@' > > HAVE_UNBOUND='@HAVE_UNBOUND@' > > +HAVE_BACKTRACE='@HAVE_BACKTRACE@' > > +HAVE_UNWIND='@HAVE_UNWIND@' > > EGREP='@EGREP@' > > PYTHON3='@PYTHON3@' > > CFLAGS='@CFLAGS@' > > diff --git a/tests/daemon.at b/tests/daemon.at > > index d7981f9d2..be8980cd4 100644 > > --- a/tests/daemon.at > > +++ b/tests/daemon.at > > @@ -234,3 +234,48 @@ OVS_WAIT_UNTIL([sc query ovsdb-server | grep STATE > | grep STOPPED > /dev/null 2> > > AT_CHECK([sc delete ovsdb-server], [0], [[[SC]] DeleteService SUCCESS > > ]) > > AT_CLEANUP > > + > > +AT_SETUP([backtrace without monitor]) > > +AT_SKIP_IF([test "$HAVE_BACKTRACE" = "no" && test "$HAVE_UNWIND" = > "no"]) > > +AT_SKIP_IF([test "$IS_WIN32" = "yes"]) > > + > > +# This test intentionally causes SIGSEGV, so make Address Sanitizer > ignore it. > > +ASAN_OPTIONS=$ASAN_OPTIONS:handle_segv=0; export ASAN_OPTIONS > > + > > +# Skip it if UB Sanitizer is being used. There's no way to disable the > > +# SEGV check at runtime. > > +AT_SKIP_IF([test $TESTS_WITH_UBSAN = yes]) > > + > > +AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --no-db --log-file > --verbose=DBG], [0], [ignore], [ignore]) > > + > > +OVS_WAIT_UNTIL([test -s ovsdb-server.pid]) > > +child=$(cat ovsdb-server.pid) > > + > > +OVS_WAIT_WHILE([kill -SEGV $child]) > > +OVS_WAIT_UNTIL([grep -q "^SIGSEGV detected, backtrace:" > ovsdb-server.log]) > > + > > +AT_CLEANUP > > + > > +AT_SETUP([backtrace with monitor]) > > +AT_SKIP_IF([test "$HAVE_BACKTRACE" = "no" && test "$HAVE_UNWIND" = > "no"]) > > +AT_SKIP_IF([test "$IS_WIN32" = "yes"]) > > + > > +# This test intentionally causes SIGSEGV, so make Address Sanitizer > ignore it. > > +ASAN_OPTIONS=$ASAN_OPTIONS:handle_segv=0; export ASAN_OPTIONS > > + > > +# Skip it if UB Sanitizer is being used. There's no way to disable the > > +# SEGV check at runtime. > > +AT_SKIP_IF([test $TESTS_WITH_UBSAN = yes]) > > + > > +on_exit 'kill $(cat *.pid)' > > + > > +AT_CHECK([ovsdb-server --detach --monitor --no-chdir --pidfile --no-db > --log-file --verbose=DBG], [0], [ignore], [ignore]) > > +OVS_WAIT_UNTIL([test -s ovsdb-server.pid]) > > +child=$(cat ovsdb-server.pid) > > + > > +OVS_WAIT_WHILE([kill -SEGV $child]) > > + > > +OVS_WAIT_UNTIL([grep -q "backtrace(monitor)|WARN|SIGSEGV detected, > backtrace:" ovsdb-server.log]) > > +OVS_WAIT_UNTIL([grep -q "daemon_unix(monitor)|ERR|1 crashes: pid .* > died, killed (Segmentation fault), core dumped, restarting" > ovsdb-server.log]) > > + > > +AT_CLEANUP > > Thanks, Ales -- Ales Musil Senior Software Engineer - OVN Core Red Hat EMEA <https://www.redhat.com> [email protected] IM: amusil <https://red.ht/sig> _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
