aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2020-03-16 12:56:56 -0700
committerMike Frysinger <vapier@chromium.org>2020-03-16 21:27:07 +0000
commite780d58fd7b6eda76065327a9921d6157e4a7964 (patch)
tree662e3c87fa98ed89d678e66405a63c7e1b3bb1c5 /src
parentconvert_UTF: try to update xcode files (diff)
downloadbreakpad-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.cc1
-rw-r--r--src/client/linux/microdump_writer/microdump_writer_unittest.cc1
-rw-r--r--src/client/linux/minidump_writer/minidump_writer_unittest.cc1
-rw-r--r--src/common/common.gyp14
-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.in3
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