diff options
author | Alexey Samsonov <vonosmas@gmail.com> | 2015-08-24 22:21:44 +0000 |
---|---|---|
committer | Alexey Samsonov <vonosmas@gmail.com> | 2015-08-24 22:21:44 +0000 |
commit | 1976cba7cb87f0b901085fdaf062b38e3f7c4208 (patch) | |
tree | e6af267044a16ff8a3853453f6c47948b59778fe /lib/sanitizer_common/sanitizer_common.cc | |
parent | 8e989c1f9e08be9153e4b8b3ecbde93f673539c8 (diff) |
[Sanitizers] Allow to install several internal Die callbacks.
This is required to properly re-apply r245770:
1) We should be able to dump coverage in __sanitizer::Die() if coverage
collection is turned on.
2) We don't want to explicitly do this in every single
sanitizer that supports it.
3) We don't want to link in coverage (and therefore symbolization) bits
into small sanitizers that don't support it (safestack).
The solution is to make InitializeCoverage() register its own Die()
callback that would call __sanitizer_cov_dump(). This callback should be
executed in addition to another tool-specific die callbacks (if there
are any).
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@245889 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_common.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.cc | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc index fb0cee0f4..4ffa5b8be 100644 --- a/lib/sanitizer_common/sanitizer_common.cc +++ b/lib/sanitizer_common/sanitizer_common.cc @@ -105,23 +105,43 @@ uptr stoptheworld_tracer_pid = 0; // writing to the same log file. uptr stoptheworld_tracer_ppid = 0; -static DieCallbackType InternalDieCallback, UserDieCallback; -void SetDieCallback(DieCallbackType callback) { - InternalDieCallback = callback; +static const int kMaxNumOfInternalDieCallbacks = 5; +static DieCallbackType InternalDieCallbacks[kMaxNumOfInternalDieCallbacks]; + +bool AddDieCallback(DieCallbackType callback) { + for (int i = 0; i < kMaxNumOfInternalDieCallbacks; i++) { + if (InternalDieCallbacks[i] == nullptr) { + InternalDieCallbacks[i] = callback; + return true; + } + } + return false; } -void SetUserDieCallback(DieCallbackType callback) { - UserDieCallback = callback; + +bool RemoveDieCallback(DieCallbackType callback) { + for (int i = 0; i < kMaxNumOfInternalDieCallbacks; i++) { + if (InternalDieCallbacks[i] == callback) { + for (int j = i + 1; j < kMaxNumOfInternalDieCallbacks; j++) + InternalDieCallbacks[j - 1] = InternalDieCallbacks[j]; + InternalDieCallbacks[kMaxNumOfInternalDieCallbacks - 1] = nullptr; + return true; + } + } + return false; } -DieCallbackType GetDieCallback() { - return InternalDieCallback; +static DieCallbackType UserDieCallback; +void SetUserDieCallback(DieCallbackType callback) { + UserDieCallback = callback; } void NORETURN Die() { if (UserDieCallback) UserDieCallback(); - if (InternalDieCallback) - InternalDieCallback(); + for (int i = kMaxNumOfInternalDieCallbacks - 1; i >= 0; i--) { + if (InternalDieCallbacks[i]) + InternalDieCallbacks[i](); + } internal__exit(common_flags()->exitcode); } |