This is a part of https://reviews.llvm.org/D95835. This change is to address two problems 1) When recording stacks in origin tracking, libunwind is not async signal safe. Inside signal callbacks, we need to use fast unwind. Fast unwind needs threads 2) StackDepot used by origin tracking is not async signal safe, we set a flag per thread inside a signal callback to prevent from using it. The thread registration is similar to ASan and MSan. Related MSan changes are *98f5ea0dba*f653cda269*5a7c364343Some changes in the diff are used in the next diffs 1) The test case pthread.c is not very interesting for now. It will be extended to test origin tracking later. 2) DFsanThread::InSignalHandler will be used by origin tracking later. Reviewed-by: morehouse Differential Revision: https://reviews.llvm.org/D95963
71 lines
1.8 KiB
C++
71 lines
1.8 KiB
C++
//===-- dfsan_thread.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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file is a part of DataFlowSanitizer.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef DFSAN_THREAD_H
|
|
#define DFSAN_THREAD_H
|
|
|
|
#include "sanitizer_common/sanitizer_common.h"
|
|
|
|
namespace __dfsan {
|
|
|
|
class DFsanThread {
|
|
public:
|
|
// NOTE: There is no DFsanThread constructor. It is allocated
|
|
// via mmap() and *must* be valid in zero-initialized state.
|
|
|
|
static DFsanThread *Create(void *start_routine_trampoline,
|
|
thread_callback_t start_routine, void *arg);
|
|
static void TSDDtor(void *tsd);
|
|
void Destroy();
|
|
|
|
void Init(); // Should be called from the thread itself.
|
|
thread_return_t ThreadStart();
|
|
|
|
uptr stack_top();
|
|
uptr stack_bottom();
|
|
bool IsMainThread() { return start_routine_ == nullptr; }
|
|
|
|
bool InSignalHandler() { return in_signal_handler_; }
|
|
void EnterSignalHandler() { in_signal_handler_++; }
|
|
void LeaveSignalHandler() { in_signal_handler_--; }
|
|
|
|
int destructor_iterations_;
|
|
|
|
private:
|
|
void SetThreadStackAndTls();
|
|
struct StackBounds {
|
|
uptr bottom;
|
|
uptr top;
|
|
};
|
|
StackBounds GetStackBounds() const;
|
|
|
|
bool AddrIsInStack(uptr addr);
|
|
|
|
void *start_routine_trampoline_;
|
|
thread_callback_t start_routine_;
|
|
void *arg_;
|
|
|
|
StackBounds stack_;
|
|
|
|
unsigned in_signal_handler_;
|
|
};
|
|
|
|
DFsanThread *GetCurrentThread();
|
|
void SetCurrentThread(DFsanThread *t);
|
|
void DFsanTSDInit(void (*destructor)(void *tsd));
|
|
void DFsanTSDDtor(void *tsd);
|
|
|
|
} // namespace __dfsan
|
|
|
|
#endif // DFSAN_THREAD_H
|