-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
[NFC][sanitizer] Add Debug utility to print thread history #111948
[NFC][sanitizer] Add Debug utility to print thread history #111948
Conversation
Created using spr 1.3.4 [skip ci]
Created using spr 1.3.4
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Vitaly Buka (vitalybuka) ChangesFull diff: https://github.com/llvm/llvm-project/pull/111948.diff 3 Files Affected:
diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
index 556a64f3017488..09391e4f5f3704 100644
--- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
@@ -94,6 +94,7 @@ set(SANITIZER_SYMBOLIZER_SOURCES
sanitizer_symbolizer_report.cpp
sanitizer_symbolizer_report_fuchsia.cpp
sanitizer_symbolizer_win.cpp
+ sanitizer_thread_history.cpp
sanitizer_unwind_linux_libcdep.cpp
sanitizer_unwind_fuchsia.cpp
sanitizer_unwind_win.cpp
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_history.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_thread_history.cpp
new file mode 100644
index 00000000000000..32a6ab1b39d3f7
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_history.cpp
@@ -0,0 +1,73 @@
+//===-- sanitizer_thread_history.cpp --------------------------------------===//
+//
+// 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 "sanitizer_thread_history.h"
+
+#include "sanitizer_stackdepot.h"
+namespace __sanitizer {
+
+void PrintThreadHistory(ThreadRegistry ®istry, InternalScopedString &out) {
+ ThreadRegistryLock l(®istry);
+ // Stack traces are largest part of printout and they offten the same for
+ // multiple threads, so we will deduplicate them.
+ InternalMmapVector<const ThreadContextBase *> stacks;
+
+ registry.RunCallbackForEachThreadLocked(
+ [](ThreadContextBase *context, void *arg) {
+ static_cast<decltype(&stacks)>(arg)->push_back(context);
+ },
+ &stacks);
+
+ Sort(stacks.data(), stacks.size(),
+ [](const ThreadContextBase *a, const ThreadContextBase *b) {
+ if (a->stack_id < b->stack_id)
+ return true;
+ if (a->stack_id > b->stack_id)
+ return false;
+ return a->tid < b->tid;
+ });
+
+ auto describe_thread = [&](const ThreadContextBase *context) {
+ if (!context) {
+ out.Append("T-1");
+ return;
+ }
+ out.AppendF("T%llu/%llu", context->unique_id, context->os_id);
+ if (internal_strlen(context->name))
+ out.AppendF(" (%s)", context->name);
+ };
+
+ auto get_parent =
+ [&](const ThreadContextBase *context) -> const ThreadContextBase * {
+ if (!context)
+ return nullptr;
+ ThreadContextBase *parent = registry.GetThreadLocked(context->parent_tid);
+ if (!parent)
+ return nullptr;
+ if (parent->unique_id >= context->unique_id)
+ return nullptr;
+ return parent;
+ };
+
+ u32 stack_id = 0;
+ for (const ThreadContextBase *context : stacks) {
+ if (stack_id != context->stack_id) {
+ StackDepotGet(stack_id).PrintTo(&out);
+ stack_id = context->stack_id;
+ }
+ out.Append("Thread ");
+ describe_thread(context);
+ out.Append(" was created by ");
+ describe_thread(get_parent(context));
+ out.Append("\n");
+ }
+ if (!stacks.empty())
+ StackDepotGet(stack_id).PrintTo(&out);
+}
+
+} // namespace __sanitizer
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_history.h b/compiler-rt/lib/sanitizer_common/sanitizer_thread_history.h
new file mode 100644
index 00000000000000..2995f6015fe50e
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_history.h
@@ -0,0 +1,24 @@
+//===-- sanitizer_thread_history.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Utility to print thread histroy from ThreadRegistry.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_THREAD_HISTORY_H
+#define SANITIZER_THREAD_HISTORY_H
+
+#include "sanitizer_thread_registry.h"
+
+namespace __sanitizer {
+
+void PrintThreadHistory(ThreadRegistry& registry, InternalScopedString& out);
+
+} // namespace __sanitizer
+
+#endif // SANITIZER_THREAD_HISTORY_H
|
Created using spr 1.3.4 [skip ci]
Will uses of |
Created using spr 1.3.4
I don't have plans to do so any time soon. Long term I am not sure. WDYT? DescribeThread prints, 1-thread + 1-stack and OK for existing application |
`parent_id` and `stack_id` represent location where the thread was created, so it's reasonable to keep them togeter. For now, only Asan and MemProf use `stack_id`, but it will be halpfull to print thread origin from other sanitizers as well. For #111948
Created using spr 1.3.4 [skip ci]
Currently, only Asan and MemProf "share" the same implementation of |
FYI, this commit seems to have introduced test failures for me, but they seem to be incidental; I've filed #112399 about it. |
…111917) `parent_id` and `stack_id` represent location where the thread was created, so it's reasonable to keep them togeter. For now, only Asan and MemProf use `stack_id`, but it will be halpfull to print thread origin from other sanitizers as well. For llvm#111948
…111917) `parent_id` and `stack_id` represent location where the thread was created, so it's reasonable to keep them togeter. For now, only Asan and MemProf use `stack_id`, but it will be halpfull to print thread origin from other sanitizers as well. For llvm#111948
For #111949