| // Copyright 2024 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/developer/debug/debug_agent/backtrace_utils.h" |
| |
| #include <stdio.h> // For fmemopen |
| |
| #include "src/developer/debug/debug_agent/process_handle.h" |
| #include "src/developer/debug/debug_agent/thread_handle.h" |
| #include "zircon/system/ulib/inspector/include/inspector/inspector.h" |
| |
| namespace debug_agent { |
| |
| std::string GetBacktraceMarkupForThread(const ProcessHandle &process, const ThreadHandle &thread) { |
| // Large binaries with lots of modules and deep stacks can produce quite a lot of markup text. 32k |
| // should be more than enough and leaves plenty of room in the rest of the FIDL message. Once the |
| // markup has been written to the string, we trim off the unused bytes below. |
| constexpr size_t kMarkupBufferMaxSize = 32768; |
| std::string backtrace_markup(kMarkupBufferMaxSize, 0); |
| |
| FILE *out = fmemopen(backtrace_markup.data(), backtrace_markup.size(), "w"); |
| fprintf(out, "{{{reset:begin}}}"); |
| inspector_print_markup_context(out, process.GetNativeHandle().get()); |
| inspector_print_backtrace_markup(out, process.GetNativeHandle().get(), |
| thread.GetNativeHandle().get()); |
| fprintf(out, "{{{reset:end}}}"); |
| |
| // The current position of the stream will tell us how large the string really needs to be. If |
| // we end up needing to pack multiple backtrace markups in a single response message, this will |
| // make sure there's no wasted space. |
| auto final_pos = ftell(out); |
| |
| fclose(out); |
| |
| backtrace_markup.resize(final_pos); |
| backtrace_markup.push_back('\0'); |
| |
| return backtrace_markup; |
| } |
| |
| } // namespace debug_agent |