mirror of
https://github.com/openvswitch/ovs
synced 2025-10-17 14:28:02 +00:00
The patch catches the SIGSEGV signal and prints the backtrace using libunwind at the monitor daemon. This makes debugging easier when there is no debug symbol package or gdb installed on production systems. The patch works when the ovs-vswitchd compiles even without debug symbol (no -g option), because the object files still have function symbols. For example: |daemon_unix(monitor)|WARN|SIGSEGV detected, backtrace: |daemon_unix(monitor)|WARN|0x0000000000482752 <fatal_signal_handler+0x52> |daemon_unix(monitor)|WARN|0x00007fb4900734b0 <killpg+0x40> |daemon_unix(monitor)|WARN|0x00007fb49013974d <__poll+0x2d> |daemon_unix(monitor)|WARN|0x000000000052b348 <time_poll+0x108> |daemon_unix(monitor)|WARN|0x00000000005153ec <poll_block+0x8c> |daemon_unix(monitor)|WARN|0x000000000058630a <clean_thread_main+0x1aa> |daemon_unix(monitor)|WARN|0x00000000004ffd1d <ovsthread_wrapper+0x7d> |daemon_unix(monitor)|WARN|0x00007fb490b3b6ba <start_thread+0xca> |daemon_unix(monitor)|WARN|0x00007fb49014541d <clone+0x6d> |daemon_unix(monitor)|ERR|1 crashes: pid 122849 died, killed \ (Segmentation fault), core dumped, restarting However, if the object files' symbols are stripped, then we can only get init function plus offset value. This is still useful when trying to see if two bugs have the same root cause, Example: |daemon_unix(monitor)|WARN|SIGSEGV detected, backtrace: |daemon_unix(monitor)|WARN|0x0000000000482752 <_init+0x7d68a> |daemon_unix(monitor)|WARN|0x00007f5f7c8cf4b0 <killpg+0x40> |daemon_unix(monitor)|WARN|0x00007f5f7c99574d <__poll+0x2d> |daemon_unix(monitor)|WARN|0x000000000052b348 <_init+0x126280> |daemon_unix(monitor)|WARN|0x00000000005153ec <_init+0x110324> |daemon_unix(monitor)|WARN|0x0000000000407439 <_init+0x2371> |daemon_unix(monitor)|WARN|0x00007f5f7c8ba830 <__libc_start_main+0xf0> |daemon_unix(monitor)|WARN|0x0000000000408329 <_init+0x3261> |daemon_unix(monitor)|ERR|1 crashes: pid 106155 died, killed \ (Segmentation fault), core dumped, restarting Most C library functions are not async-signal-safe, meaning that it is not safe to call them from a signal handler, for example printf() or fflush(). To be async-signal-safe, the handler only collects the stack info using libunwind, which is signal-safe, and issues 'write' to the pipe, where the monitor thread reads and prints to ovs-vswitchd.log. Tested-at: https://travis-ci.org/williamtu/ovs-travis/builds/590503433 Signed-off-by: William Tu <u9012063@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
94 lines
2.9 KiB
C
94 lines
2.9 KiB
C
/*
|
|
* Copyright (c) 2009 Nicira, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef BACKTRACE_H
|
|
#define BACKTRACE_H 1
|
|
|
|
#include <stdint.h>
|
|
#include "openvswitch/dynamic-string.h"
|
|
|
|
#ifdef HAVE_UNWIND
|
|
#define UNW_LOCAL_ONLY
|
|
#include <libunwind.h>
|
|
#endif
|
|
|
|
/* log_backtrace() will save the backtrace of a running program
|
|
* into the log at the DEBUG level.
|
|
*
|
|
* To use it, insert the following code to where backtrace is
|
|
* desired:
|
|
* #include "backtrace.h"
|
|
*
|
|
* log_backtrace(); <-- plain
|
|
* 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.
|
|
*
|
|
* 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)
|
|
*
|
|
* 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>
|
|
*
|
|
* 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
|
|
*
|
|
* 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
|
|
*/
|
|
|
|
#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
|
|
|
|
struct backtrace {
|
|
int n_frames;
|
|
uintptr_t frames[BACKTRACE_MAX_FRAMES];
|
|
};
|
|
|
|
#ifdef HAVE_UNWIND
|
|
#define UNW_MAX_DEPTH 32
|
|
#define UNW_MAX_FUNCN 32
|
|
#define UNW_MAX_BUF \
|
|
(UNW_MAX_DEPTH * sizeof(struct unw_backtrace))
|
|
|
|
struct unw_backtrace {
|
|
char func[UNW_MAX_FUNCN];
|
|
unw_word_t ip;
|
|
unw_word_t offset;
|
|
};
|
|
#endif
|
|
|
|
void backtrace_capture(struct backtrace *);
|
|
void log_backtrace_at(const char *msg, const char *where);
|
|
void log_received_backtrace(int fd);
|
|
|
|
#endif /* backtrace.h */
|