Skip to content

Commit fc345a7

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[vm] Also attempt a stack walk for crashes in the generated safepoint state.
TEST=ci Change-Id: I87e8ca974b915d25b8a3e84c331af9e6345f0e5a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/440320 Commit-Queue: Ryan Macnak <[email protected]> Reviewed-by: Alexander Aprelev <[email protected]>
1 parent bbb5e73 commit fc345a7

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) 2025, 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+
import "dart:io";
6+
import "dart:ffi";
7+
8+
import "package:expect/expect.dart";
9+
10+
@pragma("vm:never-inline")
11+
@pragma("vm:entry-point") /* block mangling */
12+
dartFunctionName() {
13+
Pointer<Uint8>.fromAddress(0).value = 0;
14+
}
15+
16+
@pragma("vm:never-inline")
17+
@pragma("vm:entry-point") /* block mangling */
18+
main(List<String> arguments) {
19+
if (arguments.contains("--testee")) {
20+
dartFunctionName();
21+
return;
22+
}
23+
24+
var result = Process.runSync(Platform.resolvedExecutable, [
25+
...Platform.executableArguments,
26+
Platform.script.toFilePath(),
27+
"--testee",
28+
]);
29+
print(result.exitCode);
30+
print(result.stdout);
31+
print(result.stderr);
32+
33+
Expect.contains("===== CRASH =====", result.stderr);
34+
Expect.contains("dartFunctionName", result.stderr);
35+
Expect.contains("main", result.stderr);
36+
}

runtime/vm/profiler.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,9 @@ void Profiler::DumpStackTrace(uword sp, uword fp, uword pc, bool for_crash) {
568568
StackFrame::DumpCurrentTrace();
569569
} else if (thread->execution_state() == Thread::kThreadInVM) {
570570
StackFrame::DumpCurrentTrace();
571+
} else if (thread->execution_state() == Thread::kThreadInGenerated) {
572+
// No exit frame, walk from the crash's registers.
573+
StackFrame::DumpCurrentTrace(sp, fp, pc);
571574
}
572575
}
573576

runtime/vm/stack_frame.cc

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,10 @@ const char* StackFrame::ToCString() const {
194194
code.IsNull()
195195
? "Cannot find code object"
196196
: code.QualifiedName(NameFormattingParams(Object::kInternalName));
197-
return zone->PrintToString(" pc 0x%" Pp " fp 0x%" Pp " sp 0x%" Pp " %s",
198-
pc(), fp(), sp(), name);
197+
uword offset = code.IsNull() ? 0 : pc() - code.PayloadStart();
198+
return zone->PrintToString(" pc 0x%" Pp " fp 0x%" Pp " sp 0x%" Pp
199+
" %s+0x%" Px,
200+
pc(), fp(), sp(), name, offset);
199201
}
200202

201203
void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
@@ -570,6 +572,17 @@ void StackFrame::DumpCurrentTrace() {
570572
}
571573
}
572574

575+
void StackFrame::DumpCurrentTrace(uword sp, uword fp, uword pc) {
576+
StackFrameIterator frames(fp, sp, pc, ValidationPolicy::kDontValidateFrames,
577+
Thread::Current(),
578+
StackFrameIterator::kNoCrossThreadIteration);
579+
StackFrame* frame = frames.NextFrame();
580+
while (frame != nullptr) {
581+
OS::PrintErr("%s\n", frame->ToCString());
582+
frame = frames.NextFrame();
583+
}
584+
}
585+
573586
void StackFrameIterator::SetupLastExitFrameData() {
574587
ASSERT(thread_ != nullptr);
575588
uword exit_marker = thread_->top_exit_frame_info();

runtime/vm/stack_frame.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ class StackFrame : public ValueObject {
130130
TokenPosition GetTokenPos() const;
131131

132132
static void DumpCurrentTrace();
133+
static void DumpCurrentTrace(uword sp, uword fp, uword pc);
133134

134135
uword GetCallerSp() const {
135136
return fp() +

0 commit comments

Comments
 (0)