diff options
author | Michael Forney <mforney@mforney.org> | 2020-03-16 12:56:56 -0700 |
---|---|---|
committer | Mike Frysinger <vapier@chromium.org> | 2020-03-16 21:27:07 +0000 |
commit | e780d58fd7b6eda76065327a9921d6157e4a7964 (patch) | |
tree | 662e3c87fa98ed89d678e66405a63c7e1b3bb1c5 /src | |
parent | convert_UTF: try to update xcode files (diff) | |
download | breakpad-e780d58fd7b6eda76065327a9921d6157e4a7964.tar.xz |
Use breakpad_getcontext on all Linux platforms missing getcontext
getcontext is also not available on musl libc, so generalize
breakpad_getcontext so it can be used as a fallback for non-Android
platforms as well.
On x86_64 and i386, ucontext_t uses an Android-specific offset for
storage of FP registers, since its sigset_t differs in size. So,
make the definition of MCONTEXT_FPREGS_MEM and UCONTEXT_FPREGS_MEM_OFFSET
conditional on whether we are building for Android.
On glibc and musl, signal.h and asm/sigcontext.h can't be included
together, so in breakpad_context_unittest.cc, only compare the libc
and kernel _fpstate when on Android.
Bug: google-breakpad:631
Change-Id: If81d73c4101bae946e9a3655b8d1c40a34ab6c38
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2102135
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/client/linux/handler/exception_handler.cc | 1 | ||||
-rw-r--r-- | src/client/linux/microdump_writer/microdump_writer_unittest.cc | 1 | ||||
-rw-r--r-- | src/client/linux/minidump_writer/minidump_writer_unittest.cc | 1 | ||||
-rw-r--r-- | src/common/common.gyp | 14 | ||||
-rw-r--r-- | src/common/linux/breakpad_getcontext.S (renamed from src/common/android/breakpad_getcontext.S) | 4 | ||||
-rw-r--r-- | src/common/linux/breakpad_getcontext.h (renamed from src/common/android/include/ucontext.h) | 20 | ||||
-rw-r--r-- | src/common/linux/breakpad_getcontext_unittest.cc (renamed from src/common/android/breakpad_getcontext_unittest.cc) | 14 | ||||
-rw-r--r-- | src/common/linux/ucontext_constants.h (renamed from src/common/android/ucontext_constants.h) | 21 | ||||
-rw-r--r-- | src/config.h.in | 3 |
9 files changed, 54 insertions, 25 deletions
diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index ba5b4990..c65feaa1 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -87,6 +87,7 @@ #include <vector> #include "common/basictypes.h" +#include "common/linux/breakpad_getcontext.h" #include "common/linux/linux_libc_support.h" #include "common/memory_allocator.h" #include "client/linux/log/log.h" diff --git a/src/client/linux/microdump_writer/microdump_writer_unittest.cc b/src/client/linux/microdump_writer/microdump_writer_unittest.cc index ca26fbfb..6339ac0c 100644 --- a/src/client/linux/microdump_writer/microdump_writer_unittest.cc +++ b/src/client/linux/microdump_writer/microdump_writer_unittest.cc @@ -40,6 +40,7 @@ #include "client/linux/handler/exception_handler.h" #include "client/linux/handler/microdump_extra_info.h" #include "client/linux/microdump_writer/microdump_writer.h" +#include "common/linux/breakpad_getcontext.h" #include "common/linux/eintr_wrapper.h" #include "common/linux/ignore_ret.h" #include "common/scoped_ptr.h" diff --git a/src/client/linux/minidump_writer/minidump_writer_unittest.cc b/src/client/linux/minidump_writer/minidump_writer_unittest.cc index f2b3ba38..3017a49a 100644 --- a/src/client/linux/minidump_writer/minidump_writer_unittest.cc +++ b/src/client/linux/minidump_writer/minidump_writer_unittest.cc @@ -42,6 +42,7 @@ #include "client/linux/minidump_writer/linux_dumper.h" #include "client/linux/minidump_writer/minidump_writer.h" #include "client/linux/minidump_writer/minidump_writer_unittest_utils.h" +#include "common/linux/breakpad_getcontext.h" #include "common/linux/eintr_wrapper.h" #include "common/linux/file_id.h" #include "common/linux/ignore_ret.h" diff --git a/src/common/common.gyp b/src/common/common.gyp index 103554ba..c1dbb0fe 100644 --- a/src/common/common.gyp +++ b/src/common/common.gyp @@ -33,7 +33,13 @@ 'defines': ['HAVE_MACH_O_NLIST_H'], }], ['OS=="linux"', { - 'defines': ['HAVE_A_OUT_H'], + # Assume glibc. + 'defines': ['HAVE_A_OUT_H', 'HAVE_GETCONTEXT'], + 'sources!': [ + 'linux/breakpad_getcontext.S', + 'linux/breakpad_getcontext.h', + 'linux/breakpad_getcontext_unittest.cc', + ], }], ['OS!="android"', {'sources/': [['exclude', '(^|/)android/']]}], ['OS!="linux"', {'sources/': [['exclude', '(^|/)linux/']]}], @@ -47,13 +53,11 @@ 'target_name': 'common', 'type': 'static_library', 'sources': [ - 'android/breakpad_getcontext.S', 'android/include/elf.h', 'android/include/link.h', 'android/include/stab.h', 'android/include/sys/procfs.h', 'android/include/sys/user.h', - 'android/include/ucontext.h', 'android/testing/include/wchar.h', 'android/testing/mkdtemp.h', 'android/testing/pthread_fixes.h', @@ -87,6 +91,8 @@ 'dwarf_line_to_module.h', 'language.cc', 'language.h', + 'linux/breakpad_getcontext.S', + 'linux/breakpad_getcontext.h', 'linux/crc32.cc', 'linux/crc32.h', 'linux/dump_symbols.cc', @@ -201,7 +207,6 @@ 'target_name': 'common_unittests', 'type': 'executable', 'sources': [ - 'android/breakpad_getcontext_unittest.cc', 'byte_cursor_unittest.cc', 'dwarf/bytereader_unittest.cc', 'dwarf/dwarf2diehandler_unittest.cc', @@ -210,6 +215,7 @@ 'dwarf_cfi_to_module_unittest.cc', 'dwarf_cu_to_module_unittest.cc', 'dwarf_line_to_module_unittest.cc', + 'linux/breakpad_getcontext_unittest.cc', 'linux/dump_symbols_unittest.cc', 'linux/elf_core_dump_unittest.cc', 'linux/elf_symbols_to_module_unittest.cc', diff --git a/src/common/android/breakpad_getcontext.S b/src/common/linux/breakpad_getcontext.S index 7f3a3b6f..fea0109d 100644 --- a/src/common/android/breakpad_getcontext.S +++ b/src/common/linux/breakpad_getcontext.S @@ -28,9 +28,9 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // A minimalistic implementation of getcontext() to be used by -// Google Breakpad on Android. +// Google Breakpad when getcontext() is not available in libc. -#include "common/android/ucontext_constants.h" +#include "common/linux/ucontext_constants.h" /* int getcontext (ucontext_t *ucp) */ diff --git a/src/common/android/include/ucontext.h b/src/common/linux/breakpad_getcontext.h index 29db8ade..1418cde6 100644 --- a/src/common/android/include/ucontext.h +++ b/src/common/linux/breakpad_getcontext.h @@ -27,22 +27,22 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H -#define GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H +#ifndef GOOGLE_BREAKPAD_COMMON_LINUX_INCLUDE_UCONTEXT_H +#define GOOGLE_BREAKPAD_COMMON_LINUX_INCLUDE_UCONTEXT_H -#include <sys/cdefs.h> +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif -#ifdef __BIONIC_UCONTEXT_H -#include <ucontext.h> -#else +#ifndef HAVE_GETCONTEXT -#include <sys/ucontext.h> +#include <signal.h> #ifdef __cplusplus extern "C" { #endif // __cplusplus -// Provided by src/android/common/breakpad_getcontext.S +// Provided by src/common/linux/breakpad_getcontext.S int breakpad_getcontext(ucontext_t* ucp); #define getcontext(x) breakpad_getcontext(x) @@ -51,6 +51,6 @@ int breakpad_getcontext(ucontext_t* ucp); } // extern "C" #endif // __cplusplus -#endif // __BIONIC_UCONTEXT_H +#endif // HAVE_GETCONTEXT -#endif // GOOGLE_BREAKPAD_COMMON_ANDROID_INCLUDE_UCONTEXT_H +#endif // GOOGLE_BREAKPAD_COMMON_LINUX_INCLUDE_UCONTEXT_H diff --git a/src/common/android/breakpad_getcontext_unittest.cc b/src/common/linux/breakpad_getcontext_unittest.cc index 2c550bf2..a57bfedf 100644 --- a/src/common/android/breakpad_getcontext_unittest.cc +++ b/src/common/linux/breakpad_getcontext_unittest.cc @@ -27,14 +27,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#if defined(__x86_64__) +// asm/sigcontext.h can't be included with signal.h on glibc or +// musl, so only compare _libc_fpstate and _fpstate on Android. +#if defined(__ANDROID__) && defined(__x86_64__) #include <asm/sigcontext.h> #endif #include <sys/ucontext.h> +#include <type_traits> + #include "breakpad_googletest_includes.h" -#include "common/android/ucontext_constants.h" +#include "common/linux/ucontext_constants.h" template <int left, int right> struct CompileAssertEquals { @@ -139,6 +143,8 @@ TEST(AndroidUContext, GRegsOffset) { // sigcontext is an analog to mcontext_t. The layout should be the same. COMPILE_ASSERT_EQ(offsetof(mcontext_t,fpregs), offsetof(sigcontext,fpstate), sigcontext_fpstate); + +#if defined(__ANDROID__) // Check that _fpstate from asm/sigcontext.h is essentially the same // as _libc_fpstate. COMPILE_ASSERT_EQ(sizeof(_libc_fpstate), sizeof(_fpstate), @@ -164,13 +170,15 @@ TEST(AndroidUContext, GRegsOffset) { sigcontext_fpstate_stspace); COMPILE_ASSERT_EQ(offsetof(_libc_fpstate,_xmm), offsetof(_fpstate,xmm_space), sigcontext_fpstate_xmm_space); +#endif COMPILE_ASSERT_EQ(MCONTEXT_FPREGS_PTR, offsetof(ucontext_t,uc_mcontext.fpregs), mcontext_fpregs_ptr); COMPILE_ASSERT_EQ(MCONTEXT_FPREGS_MEM, offsetof(ucontext_t,__fpregs_mem), mcontext_fpregs_mem); - COMPILE_ASSERT_EQ(FPREGS_OFFSET_MXCSR, offsetof(_libc_fpstate,mxcsr), + COMPILE_ASSERT_EQ(FPREGS_OFFSET_MXCSR, + offsetof(std::remove_pointer<fpregset_t>::type,mxcsr), fpregs_offset_mxcsr); COMPILE_ASSERT_EQ(UCONTEXT_SIGMASK_OFFSET, offsetof(ucontext_t, uc_sigmask), ucontext_sigmask); diff --git a/src/common/android/ucontext_constants.h b/src/common/linux/ucontext_constants.h index 1932d573..c390508a 100644 --- a/src/common/android/ucontext_constants.h +++ b/src/common/linux/ucontext_constants.h @@ -31,14 +31,15 @@ // Its purpose is to contain constants that must match the offsets of // various fields in ucontext_t. // -// They should match the definitions from -// src/common/android/include/sys/ucontext.h +// They should match the definitions from signal.h. // -// Used by src/common/android/breakpad_getcontext.S -// Tested by src/common/android/testing/breakpad_getcontext_unittest.cc +// Used by src/common/linux/breakpad_getcontext.S +// Tested by src/common/linux/breakpad_getcontext_unittest.cc +// +// This header should not be used by anything else. -#ifndef GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H -#define GOOGLEBREAKPAD_COMMON_ANDROID_UCONTEXT_CONSTANTS_H +#ifndef GOOGLEBREAKPAD_COMMON_LINUX_UCONTEXT_CONSTANTS_H +#define GOOGLEBREAKPAD_COMMON_LINUX_UCONTEXT_CONSTANTS_H #if defined(__arm__) @@ -93,7 +94,11 @@ #define UCONTEXT_SIGMASK_OFFSET 108 #define UCONTEXT_FPREGS_OFFSET 96 +#if defined(__BIONIC__) #define UCONTEXT_FPREGS_MEM_OFFSET 116 +#else +#define UCONTEXT_FPREGS_MEM_OFFSET 236 +#endif #elif defined(__mips__) @@ -134,7 +139,11 @@ #define MCONTEXT_GREGS_RSP 160 #define MCONTEXT_GREGS_RIP 168 #define MCONTEXT_FPREGS_PTR 224 +#if defined(__BIONIC__) #define MCONTEXT_FPREGS_MEM 304 +#else +#define MCONTEXT_FPREGS_MEM 424 +#endif #define FPREGS_OFFSET_MXCSR 24 #else diff --git a/src/config.h.in b/src/config.h.in index 618e283d..0553a24b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -9,6 +9,9 @@ /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 +/* Define to 1 if you have the `getcontext' function. */ +#undef HAVE_GETCONTEXT + /* Define to 1 if you have the `getrandom' function. */ #undef HAVE_GETRANDOM |