| //===-- InstrumentationRuntimeStopInfo.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 "lldb/Target/InstrumentationRuntimeStopInfo.h" | |
| #include "lldb/Core/Module.h" | |
| #include "lldb/Target/InstrumentationRuntime.h" | |
| #include "lldb/Target/Process.h" | |
| #include "lldb/lldb-enumerations.h" | |
| #include "lldb/lldb-private.h" | |
| using namespace lldb; | |
| using namespace lldb_private; | |
| static bool IsStoppedInDarwinSanitizer(Thread &thread, Module &module) { | |
| return module.GetFileSpec().GetFilename().starts_with("libclang_rt."); | |
| } | |
| InstrumentationRuntimeStopInfo::InstrumentationRuntimeStopInfo( | |
| Thread &thread, std::string description, | |
| StructuredData::ObjectSP additional_data) | |
| : StopInfo(thread, 0) { | |
| m_extended_info = additional_data; | |
| m_description = description; | |
| } | |
| const char *InstrumentationRuntimeStopInfo::GetDescription() { | |
| return m_description.c_str(); | |
| } | |
| StopInfoSP | |
| InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData( | |
| Thread &thread, std::string description, | |
| StructuredData::ObjectSP additionalData) { | |
| return StopInfoSP( | |
| new InstrumentationRuntimeStopInfo(thread, description, additionalData)); | |
| } | |
| std::optional<uint32_t> | |
| InstrumentationRuntimeStopInfo::GetSuggestedStackFrameIndex( | |
| bool inlined_stack) { | |
| ThreadSP thread_sp = GetThread(); | |
| if (!thread_sp) | |
| return std::nullopt; | |
| // Defensive upper-bound of when we stop walking up the frames in | |
| // case we somehow ended up looking at an infinite recursion. | |
| constexpr size_t max_stack_depth = 128; | |
| // Start at parent frame. | |
| size_t stack_idx = 1; | |
| StackFrameSP most_relevant_frame_sp = | |
| thread_sp->GetStackFrameAtIndex(stack_idx); | |
| while (most_relevant_frame_sp && stack_idx <= max_stack_depth) { | |
| auto const &sc = | |
| most_relevant_frame_sp->GetSymbolContext(lldb::eSymbolContextModule); | |
| if (!sc.module_sp) | |
| return std::nullopt; | |
| // Found a frame outside of the sanitizer runtime libraries. | |
| // That's the one we want to display. | |
| if (!IsStoppedInDarwinSanitizer(*thread_sp, *sc.module_sp)) | |
| return stack_idx; | |
| ++stack_idx; | |
| most_relevant_frame_sp = thread_sp->GetStackFrameAtIndex(stack_idx); | |
| } | |
| return stack_idx; | |
| } |