blob: dc2774b17e4c3218c1f95b3a615d0651832d817c [file] [log] [blame]
// 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