mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-01-02 12:44:38 +01:00
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>
This commit is contained in:
parent
02b7be4065
commit
e780d58fd7
14 changed files with 124 additions and 87 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue