[GWP-ASan] Minor refactor of optional components.

In preparation for the inbuilt options parser, this is a minor refactor
of optional components including:
 - Putting certain optional elements in the right header files,
 according to their function and their dependencies.
 - Cleaning up some old and mostly-dead code.
 - Moving some functions into anonymous namespaces to prevent symbol
 export.

Reviewed By: cryptoad, eugenis

Differential Revision: https://reviews.llvm.org/D94117
This commit is contained in:
Mitch Phillips 2021-01-13 17:28:10 -08:00
parent 64e9e9aeee
commit a8520f6970
13 changed files with 210 additions and 216 deletions

View File

@ -9,21 +9,45 @@
#ifndef GWP_ASAN_OPTIONAL_BACKTRACE_H_
#define GWP_ASAN_OPTIONAL_BACKTRACE_H_
#include "gwp_asan/optional/segv_handler.h"
#include "gwp_asan/optional/printf.h"
#include "gwp_asan/options.h"
namespace gwp_asan {
namespace options {
// Functions to get the platform-specific and implementation-specific backtrace
// and backtrace printing functions when RTGwpAsanBacktraceLibc or
// RTGwpAsanBacktraceSanitizerCommon are linked. Use these functions to get the
// backtrace function for populating the Options::Backtrace and
// Options::PrintBacktrace when initialising the GuardedPoolAllocator. Please
// note any thread-safety descriptions for the implementation of these functions
// that you use.
Backtrace_t getBacktraceFunction();
crash_handler::PrintBacktrace_t getPrintBacktraceFunction();
} // namespace options
namespace backtrace {
// ================================ Description ================================
// This function shall take the backtrace provided in `TraceBuffer`, and print
// it in a human-readable format using `Print`. Generally, this function shall
// resolve raw pointers to section offsets and print them with the following
// sanitizer-common format:
// " #{frame_number} {pointer} in {function name} ({binary name}+{offset}"
// e.g. " #5 0x420459 in _start (/tmp/uaf+0x420459)"
// This format allows the backtrace to be symbolized offline successfully using
// llvm-symbolizer.
// =================================== Notes ===================================
// This function may directly or indirectly call malloc(), as the
// GuardedPoolAllocator contains a reentrancy barrier to prevent infinite
// recursion. Any allocation made inside this function will be served by the
// supporting allocator, and will not have GWP-ASan protections.
typedef void (*PrintBacktrace_t)(uintptr_t *TraceBuffer, size_t TraceLength,
Printf_t Print);
// Returns a function pointer to a backtrace function that's suitable for
// unwinding through a signal handler. This is important primarily for frame-
// pointer based unwinders, DWARF or other unwinders can simply provide the
// normal backtrace function as the implementation here. On POSIX, SignalContext
// should be the `ucontext_t` from the signal handler.
typedef size_t (*SegvBacktrace_t)(uintptr_t *TraceBuffer, size_t Size,
void *SignalContext);
// Returns platform-specific provided implementations of Backtrace_t for use
// inside the GWP-ASan core allocator.
options::Backtrace_t getBacktraceFunction();
// Returns platform-specific provided implementations of PrintBacktrace_t and
// SegvBacktrace_t for use in the optional SEGV handler.
PrintBacktrace_t getPrintBacktraceFunction();
SegvBacktrace_t getSegvBacktraceFunction();
} // namespace backtrace
} // namespace gwp_asan
#endif // GWP_ASAN_OPTIONAL_BACKTRACE_H_

View File

@ -11,12 +11,11 @@
// GWP-ASan on Fuchsia doesn't currently support backtraces.
namespace gwp_asan {
namespace options {
Backtrace_t getBacktraceFunction() { return nullptr; }
crash_handler::PrintBacktrace_t getPrintBacktraceFunction() { return nullptr; }
} // namespace options
namespace backtrace {
namespace crash_handler {
options::Backtrace_t getBacktraceFunction() { return nullptr; }
PrintBacktrace_t getPrintBacktraceFunction() { return nullptr; }
SegvBacktrace_t getSegvBacktraceFunction() { return nullptr; }
} // namespace crash_handler
} // namespace backtrace
} // namespace gwp_asan

View File

@ -13,7 +13,9 @@
#include <stdlib.h>
#include <string.h>
#include "gwp_asan/definitions.h"
#include "gwp_asan/optional/backtrace.h"
#include "gwp_asan/optional/printf.h"
#include "gwp_asan/options.h"
namespace {
@ -32,7 +34,7 @@ GWP_ASAN_ALWAYS_INLINE size_t SegvBacktrace(uintptr_t *TraceBuffer, size_t Size,
}
static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength,
gwp_asan::crash_handler::Printf_t Printf) {
gwp_asan::Printf_t Printf) {
if (TraceLength == 0) {
Printf(" <not found (does your allocator support backtracing?)>\n\n");
return;
@ -55,14 +57,11 @@ static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength,
} // anonymous namespace
namespace gwp_asan {
namespace options {
Backtrace_t getBacktraceFunction() { return Backtrace; }
crash_handler::PrintBacktrace_t getPrintBacktraceFunction() {
return PrintBacktrace;
}
} // namespace options
namespace backtrace {
namespace crash_handler {
options::Backtrace_t getBacktraceFunction() { return Backtrace; }
PrintBacktrace_t getPrintBacktraceFunction() { return PrintBacktrace; }
SegvBacktrace_t getSegvBacktraceFunction() { return SegvBacktrace; }
} // namespace crash_handler
} // namespace backtrace
} // namespace gwp_asan

View File

@ -62,7 +62,7 @@ size_t SegvBacktrace(uintptr_t *TraceBuffer, size_t Size, void *Context) {
}
static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength,
gwp_asan::crash_handler::Printf_t Printf) {
gwp_asan::Printf_t Printf) {
__sanitizer::StackTrace StackTrace;
StackTrace.trace = reinterpret_cast<__sanitizer::uptr *>(Trace);
StackTrace.size = TraceLength;
@ -77,25 +77,23 @@ static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength,
} // anonymous namespace
namespace gwp_asan {
namespace options {
namespace backtrace {
// This function is thread-compatible. It must be synchronised in respect to any
// other calls to getBacktraceFunction(), calls to getPrintBacktraceFunction(),
// and calls to either of the functions that they return. Furthermore, this may
// require synchronisation with any calls to sanitizer_common that use flags.
// Generally, this function will be called during the initialisation of the
// allocator, which is done in a thread-compatible manner.
Backtrace_t getBacktraceFunction() {
options::Backtrace_t getBacktraceFunction() {
// The unwinder requires the default flags to be set.
__sanitizer::SetCommonFlagsDefaults();
__sanitizer::InitializeCommonFlags();
return Backtrace;
}
crash_handler::PrintBacktrace_t getPrintBacktraceFunction() {
return PrintBacktrace;
}
} // namespace options
namespace crash_handler {
PrintBacktrace_t getPrintBacktraceFunction() { return PrintBacktrace; }
SegvBacktrace_t getSegvBacktraceFunction() { return SegvBacktrace; }
} // namespace crash_handler
} // namespace backtrace
} // namespace gwp_asan

View File

@ -0,0 +1,33 @@
//===-- printf.h ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef GWP_ASAN_OPTIONAL_PRINTF_H_
#define GWP_ASAN_OPTIONAL_PRINTF_H_
namespace gwp_asan {
// ================================ Requirements ===============================
// This function is required to be provided by the supporting allocator iff the
// allocator wants to use any of the optional components.
// ================================ Description ================================
// This function shall produce output according to a strict subset of the C
// standard library's printf() family. This function must support printing the
// following formats:
// 1. integers: "%([0-9]*)?(z|ll)?{d,u,x,X}"
// 2. pointers: "%p"
// 3. strings: "%[-]([0-9]*)?(\\.\\*)?s"
// 4. chars: "%c"
// This function must be implemented in a signal-safe manner, and thus must not
// malloc().
// =================================== Notes ===================================
// This function has a slightly different signature than the C standard
// library's printf(). Notably, it returns 'void' rather than 'int'.
typedef void (*Printf_t)(const char *Format, ...);
} // namespace gwp_asan
#endif // GWP_ASAN_OPTIONAL_PRINTF_H_

View File

@ -10,64 +10,11 @@
#define GWP_ASAN_OPTIONAL_SEGV_HANDLER_H_
#include "gwp_asan/guarded_pool_allocator.h"
#include "gwp_asan/options.h"
#include "gwp_asan/optional/backtrace.h"
#include "gwp_asan/optional/printf.h"
namespace gwp_asan {
namespace crash_handler {
// ================================ Requirements ===============================
// This function must be provided by the supporting allocator only when this
// provided crash handler is used to dump the generic report.
// sanitizer::Printf() function can be simply used here.
// ================================ Description ================================
// This function shall produce output according to a strict subset of the C
// standard library's printf() family. This function must support printing the
// following formats:
// 1. integers: "%([0-9]*)?(z|ll)?{d,u,x,X}"
// 2. pointers: "%p"
// 3. strings: "%[-]([0-9]*)?(\\.\\*)?s"
// 4. chars: "%c"
// This function must be implemented in a signal-safe manner, and thus must not
// malloc().
// =================================== Notes ===================================
// This function has a slightly different signature than the C standard
// library's printf(). Notably, it returns 'void' rather than 'int'.
typedef void (*Printf_t)(const char *Format, ...);
// ================================ Requirements ===============================
// This function is required for the supporting allocator, but one of the three
// provided implementations may be used (RTGwpAsanBacktraceLibc,
// RTGwpAsanBacktraceSanitizerCommon, or BasicPrintBacktraceFunction).
// ================================ Description ================================
// This function shall take the backtrace provided in `TraceBuffer`, and print
// it in a human-readable format using `Print`. Generally, this function shall
// resolve raw pointers to section offsets and print them with the following
// sanitizer-common format:
// " #{frame_number} {pointer} in {function name} ({binary name}+{offset}"
// e.g. " #5 0x420459 in _start (/tmp/uaf+0x420459)"
// This format allows the backtrace to be symbolized offline successfully using
// llvm-symbolizer.
// =================================== Notes ===================================
// This function may directly or indirectly call malloc(), as the
// GuardedPoolAllocator contains a reentrancy barrier to prevent infinite
// recursion. Any allocation made inside this function will be served by the
// supporting allocator, and will not have GWP-ASan protections.
typedef void (*PrintBacktrace_t)(uintptr_t *TraceBuffer, size_t TraceLength,
Printf_t Print);
// Returns a function pointer to a basic PrintBacktrace implementation. This
// implementation simply prints the stack trace in a human readable fashion
// without any symbolization.
PrintBacktrace_t getBasicPrintBacktraceFunction();
// Returns a function pointer to a backtrace function that's suitable for
// unwinding through a signal handler. This is important primarily for frame-
// pointer based unwinders, DWARF or other unwinders can simply provide the
// normal backtrace function as the implementation here. On POSIX, SignalContext
// should be the `ucontext_t` from the signal handler.
typedef size_t (*SegvBacktrace_t)(uintptr_t *TraceBuffer, size_t Size,
void *SignalContext);
SegvBacktrace_t getSegvBacktraceFunction();
namespace segv_handler {
// Install the SIGSEGV crash handler for printing use-after-free and heap-
// buffer-{under|over}flow exceptions if the user asked for it. This is platform
// specific as even though POSIX and Windows both support registering handlers
@ -75,16 +22,12 @@ SegvBacktrace_t getSegvBacktraceFunction();
// the address that caused the SIGSEGV exception. GPA->init() must be called
// before this function.
void installSignalHandlers(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf,
PrintBacktrace_t PrintBacktrace,
SegvBacktrace_t SegvBacktrace);
gwp_asan::backtrace::PrintBacktrace_t PrintBacktrace,
gwp_asan::backtrace::SegvBacktrace_t SegvBacktrace);
// Uninistall the signal handlers, test-only.
void uninstallSignalHandlers();
void dumpReport(uintptr_t ErrorPtr, const gwp_asan::AllocatorState *State,
const gwp_asan::AllocationMetadata *Metadata,
SegvBacktrace_t SegvBacktrace, Printf_t Printf,
PrintBacktrace_t PrintBacktrace, void *Context);
} // namespace crash_handler
} // namespace segv_handler
} // namespace gwp_asan
#endif // GWP_ASAN_OPTIONAL_SEGV_HANDLER_H_

View File

@ -11,12 +11,12 @@
// GWP-ASan on Fuchsia doesn't currently support signal handlers.
namespace gwp_asan {
namespace crash_handler {
namespace segv_handler {
void installSignalHandlers(gwp_asan::GuardedPoolAllocator * /* GPA */,
Printf_t /* Printf */,
PrintBacktrace_t /* PrintBacktrace */,
SegvBacktrace_t /* SegvBacktrace */) {}
backtrace::PrintBacktrace_t /* PrintBacktrace */,
backtrace::SegvBacktrace_t /* SegvBacktrace */) {}
void uninstallSignalHandlers() {}
} // namespace crash_handler
} // namespace segv_handler
} // namespace gwp_asan

View File

@ -12,62 +12,30 @@
#include "gwp_asan/optional/segv_handler.h"
#include "gwp_asan/options.h"
// RHEL creates the PRIu64 format macro (for printing uint64_t's) only when this
// macro is defined before including <inttypes.h>.
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS 1
#endif
#include <assert.h>
#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
namespace {
using gwp_asan::AllocationMetadata;
using gwp_asan::Error;
using gwp_asan::GuardedPoolAllocator;
using gwp_asan::crash_handler::PrintBacktrace_t;
using gwp_asan::crash_handler::Printf_t;
using gwp_asan::crash_handler::SegvBacktrace_t;
using gwp_asan::Printf_t;
using gwp_asan::backtrace::PrintBacktrace_t;
using gwp_asan::backtrace::SegvBacktrace_t;
struct sigaction PreviousHandler;
bool SignalHandlerInstalled;
gwp_asan::GuardedPoolAllocator *GPAForSignalHandler;
Printf_t PrintfForSignalHandler;
PrintBacktrace_t PrintBacktraceForSignalHandler;
SegvBacktrace_t BacktraceForSignalHandler;
static void sigSegvHandler(int sig, siginfo_t *info, void *ucontext) {
if (GPAForSignalHandler) {
GPAForSignalHandler->stop();
gwp_asan::crash_handler::dumpReport(
reinterpret_cast<uintptr_t>(info->si_addr),
GPAForSignalHandler->getAllocatorState(),
GPAForSignalHandler->getMetadataRegion(), BacktraceForSignalHandler,
PrintfForSignalHandler, PrintBacktraceForSignalHandler, ucontext);
}
// Process any previous handlers.
if (PreviousHandler.sa_flags & SA_SIGINFO) {
PreviousHandler.sa_sigaction(sig, info, ucontext);
} else if (PreviousHandler.sa_handler == SIG_DFL) {
// If the previous handler was the default handler, cause a core dump.
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
} else if (PreviousHandler.sa_handler == SIG_IGN) {
// If the previous segv handler was SIGIGN, crash iff we were responsible
// for the crash.
if (__gwp_asan_error_is_mine(GPAForSignalHandler->getAllocatorState(),
reinterpret_cast<uintptr_t>(info->si_addr))) {
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
}
} else {
PreviousHandler.sa_handler(sig);
}
}
namespace {
struct ScopedEndOfReportDecorator {
ScopedEndOfReportDecorator(gwp_asan::crash_handler::Printf_t Printf)
: Printf(Printf) {}
ScopedEndOfReportDecorator(gwp_asan::Printf_t Printf) : Printf(Printf) {}
~ScopedEndOfReportDecorator() { Printf("*** End GWP-ASan report ***\n"); }
gwp_asan::crash_handler::Printf_t Printf;
gwp_asan::Printf_t Printf;
};
// Prints the provided error and metadata information.
@ -117,47 +85,6 @@ void printHeader(Error E, uintptr_t AccessPtr,
AccessPtr, DescriptionBuffer, ThreadBuffer);
}
void defaultPrintStackTrace(uintptr_t *Trace, size_t TraceLength,
gwp_asan::crash_handler::Printf_t Printf) {
if (TraceLength == 0)
Printf(" <unknown (does your allocator support backtracing?)>\n");
for (size_t i = 0; i < TraceLength; ++i) {
Printf(" #%zu 0x%zx in <unknown>\n", i, Trace[i]);
}
Printf("\n");
}
} // anonymous namespace
namespace gwp_asan {
namespace crash_handler {
PrintBacktrace_t getBasicPrintBacktraceFunction() {
return defaultPrintStackTrace;
}
void installSignalHandlers(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf,
PrintBacktrace_t PrintBacktrace,
SegvBacktrace_t SegvBacktrace) {
GPAForSignalHandler = GPA;
PrintfForSignalHandler = Printf;
PrintBacktraceForSignalHandler = PrintBacktrace;
BacktraceForSignalHandler = SegvBacktrace;
struct sigaction Action = {};
Action.sa_sigaction = sigSegvHandler;
Action.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &Action, &PreviousHandler);
SignalHandlerInstalled = true;
}
void uninstallSignalHandlers() {
if (SignalHandlerInstalled) {
sigaction(SIGSEGV, &PreviousHandler, nullptr);
SignalHandlerInstalled = false;
}
}
void dumpReport(uintptr_t ErrorPtr, const gwp_asan::AllocatorState *State,
const gwp_asan::AllocationMetadata *Metadata,
SegvBacktrace_t SegvBacktrace, Printf_t Printf,
@ -205,7 +132,7 @@ void dumpReport(uintptr_t ErrorPtr, const gwp_asan::AllocatorState *State,
// Maybe print the deallocation trace.
if (__gwp_asan_is_deallocated(AllocMeta)) {
uint64_t ThreadID = __gwp_asan_get_deallocation_thread_id(AllocMeta);
if (ThreadID == kInvalidThreadID)
if (ThreadID == gwp_asan::kInvalidThreadID)
Printf("0x%zx was deallocated by thread <unknown> here:\n", ErrorPtr);
else
Printf("0x%zx was deallocated by thread %zu here:\n", ErrorPtr, ThreadID);
@ -216,7 +143,7 @@ void dumpReport(uintptr_t ErrorPtr, const gwp_asan::AllocatorState *State,
// Print the allocation trace.
uint64_t ThreadID = __gwp_asan_get_allocation_thread_id(AllocMeta);
if (ThreadID == kInvalidThreadID)
if (ThreadID == gwp_asan::kInvalidThreadID)
Printf("0x%zx was allocated by thread <unknown> here:\n", ErrorPtr);
else
Printf("0x%zx was allocated by thread %zu here:\n", ErrorPtr, ThreadID);
@ -224,5 +151,75 @@ void dumpReport(uintptr_t ErrorPtr, const gwp_asan::AllocatorState *State,
AllocMeta, Trace, kMaximumStackFramesForCrashTrace);
PrintBacktrace(Trace, TraceLength, Printf);
}
} // namespace crash_handler
struct sigaction PreviousHandler;
bool SignalHandlerInstalled;
gwp_asan::GuardedPoolAllocator *GPAForSignalHandler;
Printf_t PrintfForSignalHandler;
PrintBacktrace_t PrintBacktraceForSignalHandler;
SegvBacktrace_t BacktraceForSignalHandler;
static void sigSegvHandler(int sig, siginfo_t *info, void *ucontext) {
if (GPAForSignalHandler) {
GPAForSignalHandler->stop();
dumpReport(reinterpret_cast<uintptr_t>(info->si_addr),
GPAForSignalHandler->getAllocatorState(),
GPAForSignalHandler->getMetadataRegion(),
BacktraceForSignalHandler, PrintfForSignalHandler,
PrintBacktraceForSignalHandler, ucontext);
}
// Process any previous handlers.
if (PreviousHandler.sa_flags & SA_SIGINFO) {
PreviousHandler.sa_sigaction(sig, info, ucontext);
} else if (PreviousHandler.sa_handler == SIG_DFL) {
// If the previous handler was the default handler, cause a core dump.
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
} else if (PreviousHandler.sa_handler == SIG_IGN) {
// If the previous segv handler was SIGIGN, crash iff we were responsible
// for the crash.
if (__gwp_asan_error_is_mine(GPAForSignalHandler->getAllocatorState(),
reinterpret_cast<uintptr_t>(info->si_addr))) {
signal(SIGSEGV, SIG_DFL);
raise(SIGSEGV);
}
} else {
PreviousHandler.sa_handler(sig);
}
}
} // anonymous namespace
namespace gwp_asan {
namespace segv_handler {
void installSignalHandlers(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf,
PrintBacktrace_t PrintBacktrace,
SegvBacktrace_t SegvBacktrace) {
assert(GPA && "GPA wasn't provided to installSignalHandlers.");
assert(Printf && "Printf wasn't provided to installSignalHandlers.");
assert(PrintBacktrace &&
"PrintBacktrace wasn't provided to installSignalHandlers.");
assert(SegvBacktrace &&
"SegvBacktrace wasn't provided to installSignalHandlers.");
GPAForSignalHandler = GPA;
PrintfForSignalHandler = Printf;
PrintBacktraceForSignalHandler = PrintBacktrace;
BacktraceForSignalHandler = SegvBacktrace;
struct sigaction Action = {};
Action.sa_sigaction = sigSegvHandler;
Action.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &Action, &PreviousHandler);
SignalHandlerInstalled = true;
}
void uninstallSignalHandlers() {
if (SignalHandlerInstalled) {
sigaction(SIGSEGV, &PreviousHandler, nullptr);
SignalHandlerInstalled = false;
}
}
} // namespace segv_handler
} // namespace gwp_asan

View File

@ -10,7 +10,7 @@ set(GWP_ASAN_UNITTEST_CFLAGS
file(GLOB GWP_ASAN_HEADERS ../*.h)
set(GWP_ASAN_UNITTESTS
optional/printf_sanitizer_common.cpp
platform_specific/printf_sanitizer_common.cpp
alignment.cpp
backtrace.cpp
basic.cpp

View File

@ -21,6 +21,7 @@ using Test = ::testing::Test;
#include "gwp_asan/guarded_pool_allocator.h"
#include "gwp_asan/optional/backtrace.h"
#include "gwp_asan/optional/printf.h"
#include "gwp_asan/optional/segv_handler.h"
#include "gwp_asan/options.h"
@ -30,7 +31,7 @@ namespace test {
// their own signal-safe Printf function. In LLVM, we use
// `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf
// for this purpose.
crash_handler::Printf_t getPrintfFunction();
Printf_t getPrintfFunction();
// First call returns true, all the following calls return false.
bool OnlyOnce();
@ -86,19 +87,19 @@ public:
gwp_asan::options::Options Opts;
Opts.setDefaults();
Opts.Backtrace = gwp_asan::options::getBacktraceFunction();
Opts.Backtrace = gwp_asan::backtrace::getBacktraceFunction();
Opts.InstallForkHandlers = gwp_asan::test::OnlyOnce();
GPA.init(Opts);
gwp_asan::crash_handler::installSignalHandlers(
gwp_asan::segv_handler::installSignalHandlers(
&GPA, gwp_asan::test::getPrintfFunction(),
gwp_asan::options::getPrintBacktraceFunction(),
gwp_asan::crash_handler::getSegvBacktraceFunction());
gwp_asan::backtrace::getPrintBacktraceFunction(),
gwp_asan::backtrace::getSegvBacktraceFunction());
}
void TearDown() override {
GPA.uninitTestOnly();
gwp_asan::crash_handler::uninstallSignalHandlers();
gwp_asan::segv_handler::uninstallSignalHandlers();
}
protected:

View File

@ -6,15 +6,14 @@
//
//===----------------------------------------------------------------------===//
#include "gwp_asan/optional/segv_handler.h"
#include "gwp_asan/optional/printf.h"
#include "sanitizer_common/sanitizer_common.h"
namespace gwp_asan {
namespace test {
// This printf-function getter allows other platforms (e.g. Android) to define
// their own signal-safe Printf function. In LLVM, we use
// `optional/printf_sanitizer_common.cpp` which supplies the __sanitizer::Printf
// for this purpose.
crash_handler::Printf_t getPrintfFunction() { return __sanitizer::Printf; }
}; // namespace test
}; // namespace gwp_asan
Printf_t getPrintfFunction() { return __sanitizer::Printf; }
} // namespace test
} // namespace gwp_asan

View File

@ -674,14 +674,14 @@ void initScudo() {
#ifdef GWP_ASAN_HOOKS
gwp_asan::options::initOptions();
gwp_asan::options::Options &Opts = gwp_asan::options::getOptions();
Opts.Backtrace = gwp_asan::options::getBacktraceFunction();
Opts.Backtrace = gwp_asan::backtrace::getBacktraceFunction();
GuardedAlloc.init(Opts);
if (Opts.InstallSignalHandlers)
gwp_asan::crash_handler::installSignalHandlers(
gwp_asan::segv_handler::installSignalHandlers(
&GuardedAlloc, __sanitizer::Printf,
gwp_asan::options::getPrintBacktraceFunction(),
gwp_asan::crash_handler::getSegvBacktraceFunction());
gwp_asan::backtrace::getPrintBacktraceFunction(),
gwp_asan::backtrace::getSegvBacktraceFunction());
#endif // GWP_ASAN_HOOKS
}

View File

@ -198,13 +198,14 @@ public:
// Allocator::disable calling GWPASan.disable). Disable GWP-ASan's atfork
// handler.
Opt.InstallForkHandlers = false;
Opt.Backtrace = gwp_asan::options::getBacktraceFunction();
Opt.Backtrace = gwp_asan::backtrace::getBacktraceFunction();
GuardedAlloc.init(Opt);
if (Opt.InstallSignalHandlers)
gwp_asan::crash_handler::installSignalHandlers(
&GuardedAlloc, Printf, gwp_asan::options::getPrintBacktraceFunction(),
gwp_asan::crash_handler::getSegvBacktraceFunction());
gwp_asan::segv_handler::installSignalHandlers(
&GuardedAlloc, Printf,
gwp_asan::backtrace::getPrintBacktraceFunction(),
gwp_asan::backtrace::getSegvBacktraceFunction());
#endif // GWP_ASAN_HOOKS
}
@ -219,7 +220,7 @@ public:
Primary.unmapTestOnly();
#ifdef GWP_ASAN_HOOKS
if (getFlags()->GWP_ASAN_InstallSignalHandlers)
gwp_asan::crash_handler::uninstallSignalHandlers();
gwp_asan::segv_handler::uninstallSignalHandlers();
GuardedAlloc.uninitTestOnly();
#endif // GWP_ASAN_HOOKS
}