crashpad/compat/mac/mach-o/getsect.cc
Mark Mentovai 1baff4ff92 Accept non-fatal resource exceptions without generating crash reports.
This adds IsExceptionNonfatalResource() and its test, and uses it in
crashpad_handler. When non-fatal resource exceptions are encountered, no
crash report is generated. crashpad_handler swallows these exceptions.
Alternatively, it could allow them to be sent to the system’s host-level
resource exception handler, normally com.apple.ReportCrash.root, which
would allow them to be processed in the same way as when Crashpad is not
in use. I’m not sure which option is better. I chose to swallow them
because there doesn’t appear to be much value in letting
com.apple.ReportCrash.root and spindump look at them.

This also moves ExcCrashRecoverOriginalException() to the new file as a
sibling of IsExceptionNonfatalResource(). This provides better
organization.

BUG=crashpad:35, chromium:474163, chromium:474326
TEST=crashpad_util_test ExceptionTypes.IsExceptionNonfatalResource
R=rsesek@chromium.org

Review URL: https://codereview.chromium.org/1066243002
2015-04-08 17:46:09 -04:00

108 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// 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.
#include <mach-o/getsect.h>
// This is only necessary when building code that might run on systems earlier
// than 10.7. When building for 10.7 or later, getsectiondata() and
// getsegmentdata() are always present in libmacho and made available through
// libSystem. When building for earlier systems, custom definitions of
// these functions are needed.
//
// This file checks the deployment target instead of the SDK. The deployment
// target is correct because it identifies the earliest possible system that
// the code being compiled is expected to run on.
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
#include <dlfcn.h>
#include <stddef.h>
#include "third_party/apple_cctools/cctools/include/mach-o/getsect.h"
namespace {
// Returns a dlopen() handle to the same library that provides the
// getsectbyname() function. getsectbyname() is always present in libmacho.
// getsectiondata() and getsegmentdata() are not always present, but when they
// are, theyre in the same library as getsectbyname(). If the library cannot
// be found or a handle to it cannot be returned, returns nullptr.
void* SystemLibMachOHandle() {
Dl_info info;
if (!dladdr(reinterpret_cast<void*>(getsectbyname), &info)) {
return nullptr;
}
return dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
}
// Returns a function pointer to a function in libmacho based on a lookup of
// that function by symbol name. Returns nullptr if libmacho cannot be found or
// opened, or if the named symbol cannot be found in libmacho.
void* LookUpSystemLibMachOSymbol(const char* symbol) {
static void* dl_handle = SystemLibMachOHandle();
if (!dl_handle) {
return nullptr;
}
return dlsym(dl_handle, symbol);
}
#ifndef __LP64__
using MachHeader = mach_header;
#else
using MachHeader = mach_header_64;
#endif
using GetSectionDataType =
uint8_t*(*)(const MachHeader*, const char*, const char*, unsigned long*);
using GetSegmentDataType =
uint8_t*(*)(const MachHeader*, const char*, unsigned long*);
} // namespace
extern "C" {
// These implementations look up their functions in libmacho at run time. If
// the system libmacho provides these functions as it normally does on Mac OS X
// 10.7 and later, the systems versions are used directly. Otherwise, the
// versions in third_party/apple_cctools are used, which are actually just
// copies of the systems functions.
uint8_t* getsectiondata(const MachHeader* mhp,
const char* segname,
const char* sectname,
unsigned long* size) {
static GetSectionDataType system_getsectiondata =
reinterpret_cast<GetSectionDataType>(
LookUpSystemLibMachOSymbol("getsectiondata"));
if (system_getsectiondata) {
return system_getsectiondata(mhp, segname, sectname, size);
}
return crashpad_getsectiondata(mhp, segname, sectname, size);
}
uint8_t* getsegmentdata(
const MachHeader* mhp, const char* segname, unsigned long* size) {
static GetSegmentDataType system_getsegmentdata =
reinterpret_cast<GetSegmentDataType>(
LookUpSystemLibMachOSymbol("getsegmentdata"));
if (system_getsegmentdata) {
return system_getsegmentdata(mhp, segname, size);
}
return crashpad_getsegmentdata(mhp, segname, size);
}
} // extern "C"
#endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7