-
Notifications
You must be signed in to change notification settings - Fork 745
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NFC][sanitizer] Add Debug utility to print thread history (#111948)
For #111949
- Loading branch information
1 parent
e1cff8b
commit aa44f59
Showing
4 changed files
with
157 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
compiler-rt/lib/sanitizer_common/sanitizer_thread_history.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
//===-- 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 often 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->unique_id < b->unique_id; | ||
}); | ||
|
||
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; | ||
}; | ||
|
||
const ThreadContextBase *prev = nullptr; | ||
for (const ThreadContextBase *context : stacks) { | ||
if (prev && prev->stack_id != context->stack_id) | ||
StackDepotGet(prev->stack_id).PrintTo(&out); | ||
prev = context; | ||
out.Append("Thread "); | ||
describe_thread(context); | ||
out.Append(" was created by "); | ||
describe_thread(get_parent(context)); | ||
out.Append("\n"); | ||
} | ||
if (prev) | ||
StackDepotGet(prev->stack_id).PrintTo(&out); | ||
} | ||
|
||
} // namespace __sanitizer |
24 changes: 24 additions & 0 deletions
24
compiler-rt/lib/sanitizer_common/sanitizer_thread_history.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters