[vm] Update gdb helpers.

- Take raw addresses instead of ObjectPtr. gdb seems to sometimes not understand how to do the cast.
 - Use newer "retain" attribute to disable linker GC instead of exporting a dynamic symbol.
 - Add helper to get the current thread. Directly accessing dart::OSThread::current_vm_thread_ doesn't work.
 - Add helper to find the function or stub for a PC and disassemble.

TEST=gdb
Change-Id: I3825a820194673a9a9d5153cd0e0cf175acab5f4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363403
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak 2024-04-18 16:35:58 +00:00 committed by Commit Queue
parent d82385e372
commit 5187dbfffe
5 changed files with 78 additions and 36 deletions

View file

@ -3,22 +3,54 @@
// BSD-style license that can be found in the LICENSE file.
#include "lib/stacktrace.h"
#include "vm/compiler/assembler/disassembler.h"
#include "vm/heap/safepoint.h"
#include "vm/object.h"
#include "vm/os_thread.h"
#include "vm/stack_frame.h"
namespace dart {
#if !defined(PRODUCT)
DART_EXPORT
void _printObjectPtr(ObjectPtr object) {
OS::PrintErr("%s\n", Object::Handle(object).ToCString());
#if defined(__GNUC__)
// Older toolchains don't know about "retain"
#pragma GCC diagnostic ignored "-Wattributes"
#define GDB_HELPER extern "C" __attribute__((used, retain))
#else
#define GDB_HELPER extern "C"
#endif
GDB_HELPER
void* _currentThread() {
return OSThread::CurrentVMThread();
}
DART_EXPORT
Object* _handle(ObjectPtr object) {
return &Object::Handle(object);
GDB_HELPER
void _printObjectPtr(uword object) {
OS::PrintErr("%s\n",
Object::Handle(static_cast<ObjectPtr>(object)).ToCString());
}
GDB_HELPER
Object* _handle(uword object) {
return &Object::Handle(static_cast<ObjectPtr>(object));
}
GDB_HELPER
void _disassemble(uword pc) {
Code& code = Code::Handle(Code::FindCodeUnsafe(pc));
if (code.IsNull()) {
OS::PrintErr("No code found\n");
} else {
Object& owner = Object::Handle(code.owner());
if (owner.IsFunction()) {
Disassembler::DisassembleCode(Function::Cast(owner), code,
code.is_optimized());
} else {
Disassembler::DisassembleStub(code.Name(), code);
}
}
}
// An utility method for convenient printing of dart stack traces when
@ -26,7 +58,7 @@ Object* _handle(ObjectPtr object) {
// valid exit frame information. It will not work when a breakpoint is
// set in dart code and control is got inside 'gdb' without going through
// the runtime or native transition stub.
DART_EXPORT
GDB_HELPER
void _printDartStackTrace() {
const StackTrace& stacktrace = GetCurrentStackTrace(0);
OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());
@ -34,14 +66,16 @@ void _printDartStackTrace() {
// Like _printDartStackTrace, but works in a NoSafepointScope. Use it if you're
// in the middle of a GC or interested in stub frames.
DART_EXPORT
GDB_HELPER
void _printStackTrace() {
StackFrame::DumpCurrentTrace();
}
// Like _printDartStackTrace, but works when stopped in generated code.
// Must be called with the current fp, sp, and pc.
DART_EXPORT
// Must be called with the current fp, sp, and pc. I.e.,
//
// (gdb) print _printGeneratedStackTrace($rbp, $rsp, $rip)
GDB_HELPER
void _printGeneratedStackTrace(uword fp, uword sp, uword pc) {
StackFrameIterator frames(fp, sp, pc, ValidationPolicy::kDontValidateFrames,
Thread::Current(),
@ -77,7 +111,7 @@ class PrintObjectPointersVisitor : public ObjectPointerVisitor {
#endif
};
DART_EXPORT
GDB_HELPER
void _printStackTraceWithLocals() {
PrintObjectPointersVisitor visitor;
StackFrameIterator frames(ValidationPolicy::kDontValidateFrames,

View file

@ -497,7 +497,7 @@ class PageSpace {
friend class ConcurrentSweeperTask;
friend class GCCompactor;
friend class CompactorTask;
friend void DumpStackFrame(intptr_t frame_index, uword pc, uword fp);
friend class Code;
DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace);
};

View file

@ -18263,6 +18263,36 @@ CodePtr Code::FindCode(uword pc, int64_t timestamp) {
return visitor.result();
}
CodePtr Code::FindCodeUnsafe(uword pc) {
class FindCodeUnsafeVisitor : public ObjectVisitor {
public:
explicit FindCodeUnsafeVisitor(uword pc) : pc_(pc), result_(Code::null()) {}
void VisitObject(ObjectPtr obj) {
if (obj->IsCode()) {
CodePtr code = static_cast<CodePtr>(obj);
if (Code::ContainsInstructionAt(code, pc_)) {
result_ = code;
}
}
}
CodePtr result() { return result_; }
private:
uword pc_;
CodePtr result_;
};
IsolateGroup* group = IsolateGroup::Current();
PageSpace* old_space = group->heap()->old_space();
old_space->MakeIterable();
FindCodeUnsafeVisitor visitor(pc);
old_space->VisitObjectsUnsafe(&visitor);
Dart::vm_isolate_group()->heap()->old_space()->VisitObjectsUnsafe(&visitor);
return visitor.result();
}
TokenPosition Code::GetTokenIndexOfPC(uword pc) const {
uword pc_offset = pc - PayloadStart();
const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());

View file

@ -7156,6 +7156,7 @@ class Code : public Object {
#endif
static CodePtr FindCode(uword pc, int64_t timestamp);
static CodePtr FindCodeUnsafe(uword pc);
int32_t GetPointerOffsetAt(int index) const {
NoSafepointScope no_safepoint;

View file

@ -106,31 +106,8 @@ void DumpStackFrame(intptr_t frame_index, uword pc, uword fp) {
(thread->execution_state() != Thread::kThreadInNative) &&
(thread->execution_state() != Thread::kThreadInVM);
if (symbolize_jit_code) {
IsolateGroup* group = thread->isolate_group();
class FindCodeVisitor : public ObjectVisitor {
public:
explicit FindCodeVisitor(uword pc, Code& result)
: pc_(pc), result_(result) {}
void VisitObject(ObjectPtr obj) {
if (obj->IsCode()) {
CodePtr code = static_cast<CodePtr>(obj);
if (Code::ContainsInstructionAt(code, pc_)) {
result_ = code;
}
}
}
private:
uword pc_;
Code& result_;
};
PageSpace* old_space = group->heap()->old_space();
old_space->MakeIterable();
Code result;
result = Code::null();
FindCodeVisitor visitor(lookup_pc, result);
old_space->VisitObjectsUnsafe(&visitor);
Dart::vm_isolate_group()->heap()->old_space()->VisitObjectsUnsafe(&visitor);
result = Code::FindCodeUnsafe(lookup_pc);
if (!result.IsNull()) {
DumpStackFrame(
pc, fp,