Summary: Forewarning: This patch looks big in #LOC changed. I promise it's not that bad, it just moves a lot of content from one file to another. I've gone ahead and left inline comments on Phabricator for sections where this has happened. This patch: 1. Introduces the crash handler API (crash_handler_api.h). 2. Moves information required for out-of-process crash handling into an AllocatorState. This is a trivially-copied POD struct that designed to be recovered from a deceased process, and used by the crash handler to create a GWP-ASan report (along with the other trivially-copied Metadata struct). 3. Implements the crash handler API using the AllocatorState and Metadata. 4. Adds tests for the crash handler. 5. Reimplements the (now optionally linked by the supporting allocator) in-process crash handler (i.e. the segv handler) using the new crash handler API. 6. Minor updates Scudo & Scudo Standalone to fix compatibility. 7. Changed capitalisation of errors (e.g. /s/Use after free/Use After Free). Reviewers: cryptoad, eugenis, jfb Reviewed By: eugenis Subscribers: merge_guards_bot, pcc, jfb, dexonsmith, mgorny, cryptoad, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D73557
92 lines
2.5 KiB
C++
92 lines
2.5 KiB
C++
//===-- options_parser.cpp --------------------------------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "gwp_asan/optional/options_parser.h"
|
|
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "gwp_asan/options.h"
|
|
#include "sanitizer_common/sanitizer_common.h"
|
|
#include "sanitizer_common/sanitizer_flag_parser.h"
|
|
#include "sanitizer_common/sanitizer_flags.h"
|
|
|
|
namespace gwp_asan {
|
|
namespace options {
|
|
namespace {
|
|
void registerGwpAsanFlags(__sanitizer::FlagParser *parser, Options *o) {
|
|
#define GWP_ASAN_OPTION(Type, Name, DefaultValue, Description) \
|
|
RegisterFlag(parser, #Name, Description, &o->Name);
|
|
#include "gwp_asan/options.inc"
|
|
#undef GWP_ASAN_OPTION
|
|
}
|
|
|
|
const char *getCompileDefinitionGwpAsanDefaultOptions() {
|
|
#ifdef GWP_ASAN_DEFAULT_OPTIONS
|
|
return SANITIZER_STRINGIFY(GWP_ASAN_DEFAULT_OPTIONS);
|
|
#else
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
const char *getGwpAsanDefaultOptions() {
|
|
return (__gwp_asan_default_options) ? __gwp_asan_default_options() : "";
|
|
}
|
|
|
|
Options *getOptionsInternal() {
|
|
static Options GwpAsanFlags;
|
|
return &GwpAsanFlags;
|
|
}
|
|
} // anonymous namespace
|
|
|
|
void initOptions() {
|
|
__sanitizer::SetCommonFlagsDefaults();
|
|
|
|
Options *o = getOptionsInternal();
|
|
o->setDefaults();
|
|
|
|
__sanitizer::FlagParser Parser;
|
|
registerGwpAsanFlags(&Parser, o);
|
|
|
|
// Override from compile definition.
|
|
Parser.ParseString(getCompileDefinitionGwpAsanDefaultOptions());
|
|
|
|
// Override from user-specified string.
|
|
Parser.ParseString(getGwpAsanDefaultOptions());
|
|
|
|
// Override from environment.
|
|
Parser.ParseString(__sanitizer::GetEnv("GWP_ASAN_OPTIONS"));
|
|
|
|
__sanitizer::InitializeCommonFlags();
|
|
if (__sanitizer::Verbosity())
|
|
__sanitizer::ReportUnrecognizedFlags();
|
|
|
|
if (!o->Enabled)
|
|
return;
|
|
|
|
// Sanity checks for the parameters.
|
|
if (o->MaxSimultaneousAllocations <= 0) {
|
|
__sanitizer::Printf("GWP-ASan ERROR: MaxSimultaneousAllocations must be > "
|
|
"0 when GWP-ASan is enabled.\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if (o->SampleRate < 1) {
|
|
__sanitizer::Printf(
|
|
"GWP-ASan ERROR: SampleRate must be > 0 when GWP-ASan is enabled.\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
Options &getOptions() { return *getOptionsInternal(); }
|
|
|
|
} // namespace options
|
|
} // namespace gwp_asan
|