Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux: Be more aggressive about keeping the memory tracker on. #2243

Merged
merged 1 commit into from
Sep 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions core/memory_tracker/cc/memory_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ std::vector<void*> DirtyPageTable::DumpAndClearAll() {

template <>
bool MemoryTracker::AddTrackingRangeImpl(void* start, size_t size) {
if (!EnableMemoryTrackerImpl()) {
return false;
}

if (size == 0) return false;
if (IsInRanges(reinterpret_cast<uintptr_t>(start), ranges_)) return false;

Expand Down
2 changes: 1 addition & 1 deletion core/memory_tracker/cc/memory_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ inline bool IsInRanges(uintptr_t addr, std::map<uintptr_t, size_t>& ranges,
return true;
}

// SpinLock is a spin lock implemented with atomic variable and opertions.
// SpinLock is a spin lock implemented with atomic variable and operations.
// Mutiple calls to Lock in a single thread will result into a deadlock.
class SpinLock {
public:
Expand Down
55 changes: 27 additions & 28 deletions core/memory_tracker/cc/posix/memory_tracker.inc
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,25 @@
* limitations under the License.
*/


#include <functional>
namespace gapii {
namespace track_memory {

class PosixMemoryTracker {
public:
PosixMemoryTracker(std::function<bool(void*)> segfault_function):
signal_handler_registered_(false),
orig_action_{0},
handle_segfault_(segfault_function) {
}

public:
PosixMemoryTracker(std::function<bool(void *)> segfault_function)
: orig_action_{0}, handle_segfault_(segfault_function) {}

bool IsInstalled() const { return signal_handler_registered_; }
bool IsInstalled() const {
struct sigaction orig_action = {0};
sigaction(SIGSEGV, nullptr, &orig_action);
return orig_action.sa_sigaction == &SegfaultHandlerFunction;
}

protected:
protected:
// A static wrapper of HandleSegfault() as sigaction() asks for a static
// function.
static void SegfaultHandlerFunction(int sig, siginfo_t* info, void* unused);
static void SegfaultHandlerFunction(int sig, siginfo_t *info, void *unused);

// EnableMemoryTrackerImpl calls sigaction() to register the new segfault
// handler to the thread (and affects all the child threads), stores the
Expand All @@ -49,45 +48,45 @@ class PosixMemoryTracker {
// othwerwise returns false.
bool inline DisableMemoryTrackerImpl();

private:
bool signal_handler_registered_; // A flag to indicate whether the signal
// handler has been registered
struct sigaction orig_action_; // The original signal action for SIGSEGV
std::function<bool(void*)> handle_segfault_; // The function to call on a segfault
private:
struct sigaction orig_action_; // The original signal action for SIGSEGV
std::function<bool(void *)>
handle_segfault_; // The function to call on a segfault
};

typedef MemoryTrackerImpl<PosixMemoryTracker> MemoryTracker;
extern PosixMemoryTracker* unique_tracker;
extern PosixMemoryTracker *unique_tracker;

void inline PosixMemoryTracker::SegfaultHandlerFunction(int sig, siginfo_t* info, void* unused) {
void inline PosixMemoryTracker::SegfaultHandlerFunction(int sig,
siginfo_t *info,
void *unused) {
if (unique_tracker) {
if (!unique_tracker->handle_segfault_(info->si_addr)) {
#ifndef NDEBUG
raise(SIGTRAP);
#endif // NDEBUG
(*unique_tracker->orig_action_.sa_sigaction)(sig, info, unused);
#ifndef NDEBUG
raise(SIGTRAP);
#endif // NDEBUG
(*unique_tracker->orig_action_.sa_sigaction)(sig, info, unused);
}
}
}

bool inline PosixMemoryTracker::EnableMemoryTrackerImpl() {
if (signal_handler_registered_) {
if (IsInstalled()) {
return true;
}

unique_tracker = this;
struct sigaction sa {
0
};
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = SegfaultHandlerFunction;
signal_handler_registered_ = sigaction(SIGSEGV, &sa, &orig_action_) != 1;
return signal_handler_registered_;
sa.sa_sigaction = &SegfaultHandlerFunction;
return sigaction(SIGSEGV, &sa, &orig_action_) != 1;
}

bool inline PosixMemoryTracker::DisableMemoryTrackerImpl() {
if (signal_handler_registered_) {
signal_handler_registered_ = false;
if (IsInstalled()) {
return sigaction(SIGSEGV, &orig_action_, nullptr) != 1;
}
return true;
Expand Down