1// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "lib/stacktrace.h"
6#include "vm/heap/safepoint.h"
7#include "vm/object.h"
8#include "vm/stack_frame.h"
9
10namespace dart {
11
12#if !defined(PRODUCT)
13
14DART_EXPORT
15void _printRawObject(ObjectPtr object) {
16 OS::PrintErr("%s\n", Object::Handle(object).ToCString());
17}
18
19DART_EXPORT
20Object* _handle(ObjectPtr object) {
21 return &Object::Handle(object);
22}
23
24// An utility method for convenient printing of dart stack traces when
25// inside 'gdb'. Note: This function will only work when there is a
26// valid exit frame information. It will not work when a breakpoint is
27// set in dart code and control is got inside 'gdb' without going through
28// the runtime or native transition stub.
29DART_EXPORT
30void _printDartStackTrace() {
31 const StackTrace& stacktrace = GetCurrentStackTrace(0);
32 OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());
33}
34
35// Like _printDartStackTrace, but works in a NoSafepointScope. Use it if you're
36// in the middle of a GC or interested in stub frames.
37DART_EXPORT
38void _printStackTrace() {
39 StackFrame::DumpCurrentTrace();
40}
41
42// Like _printDartStackTrace, but works when stopped in generated code.
43// Must be called with the current fp, sp, and pc.
44DART_EXPORT
45void _printGeneratedStackTrace(uword fp, uword sp, uword pc) {
46 StackFrameIterator frames(fp, sp, pc, ValidationPolicy::kDontValidateFrames,
47 Thread::Current(),
48 StackFrameIterator::kNoCrossThreadIteration);
49 StackFrame* frame = frames.NextFrame();
50 while (frame != nullptr) {
51 OS::PrintErr("%s\n", frame->ToCString());
52 frame = frames.NextFrame();
53 }
54}
55
56// Like _printDartStackTrace, but works in the interpreter loop.
57// Must be called with the current interpreter fp, sp, and pc.
58// Note that sp[0] is not modified, but sp[1] will be trashed.
59DART_EXPORT
60void _printInterpreterStackTrace(ObjectPtr* fp,
61 ObjectPtr* sp,
62 const KBCInstr* pc) {
63 Thread* thread = Thread::Current();
64 sp[1] = Function::null();
65 sp[2] = Bytecode::null();
66 sp[3] = static_cast<ObjectPtr>(reinterpret_cast<uword>(pc));
67 sp[4] = static_cast<ObjectPtr>(reinterpret_cast<uword>(fp));
68 ObjectPtr* exit_fp = sp + 1 + kKBCDartFrameFixedSize;
69 thread->set_top_exit_frame_info(reinterpret_cast<uword>(exit_fp));
70 thread->set_execution_state(Thread::kThreadInVM);
71 _printDartStackTrace();
72 thread->set_execution_state(Thread::kThreadInGenerated);
73 thread->set_top_exit_frame_info(0);
74}
75
76class PrintObjectPointersVisitor : public ObjectPointerVisitor {
77 public:
78 PrintObjectPointersVisitor()
79 : ObjectPointerVisitor(IsolateGroup::Current()) {}
80
81 void VisitPointers(ObjectPtr* first, ObjectPtr* last) {
82 for (ObjectPtr* p = first; p <= last; p++) {
83 Object& obj = Object::Handle(*p);
84 OS::PrintErr("%p: %s\n", p, obj.ToCString());
85 }
86 }
87};
88
89DART_EXPORT
90void _printStackTraceWithLocals() {
91 PrintObjectPointersVisitor visitor;
92 StackFrameIterator frames(ValidationPolicy::kDontValidateFrames,
93 Thread::Current(),
94 StackFrameIterator::kNoCrossThreadIteration);
95 StackFrame* frame = frames.NextFrame();
96 while (frame != nullptr) {
97 OS::PrintErr("%s\n", frame->ToCString());
98 frame->VisitObjectPointers(&visitor);
99 frame = frames.NextFrame();
100 }
101}
102
103#endif // !PRODUCT
104
105} // namespace dart
106