Skip to content

Commit e01fad7

Browse files
sstricklCommit Queue
authored andcommitted
[vm,dyn_modules] Fix Scope check in ActivationFrame::ContextLevel.
The end PC offset for the scope is inclusive, not exclusive. Also rename PrintDescriptorsError -> PrintContextLevelError and print the Bytecode local variable information since that is what is searched for the context level for interpreted frames. TEST=pkg/vm_service/test/step_through_closure pkg/vm_service/test/step_through_function_expression Cq-Include-Trybots: luci.dart.try:vm-dyn-linux-debug-x64-try,vm-aot-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try,vm-dyn-mac-debug-arm64-try Change-Id: Ib53d0a7cff81de16c957b73ce9ec7dcb0e4aaa34 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/449740 Reviewed-by: Alexander Markov <[email protected]> Commit-Queue: Tess Strickland <[email protected]>
1 parent 2042850 commit e01fad7

File tree

5 files changed

+106
-81
lines changed

5 files changed

+106
-81
lines changed

runtime/vm/compiler/assembler/disassembler_kbc.cc

Lines changed: 4 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "platform/assert.h"
1111
#include "vm/bytecode_reader.h"
1212
#include "vm/constants_kbc.h"
13+
#include "vm/zone_text_buffer.h"
1314

1415
namespace dart {
1516

@@ -354,23 +355,6 @@ void KernelBytecodeDisassembler::Disassemble(uword start,
354355
#endif
355356
}
356357

357-
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
358-
static const int kLocalVariableKindMaxWidth = strlen(
359-
bytecode::BytecodeLocalVariablesIterator::kKindNames
360-
[bytecode::BytecodeLocalVariablesIterator::kVariableDeclaration]);
361-
362-
static const int kLocalVariableColumnWidths[] = {
363-
kLocalVariableKindMaxWidth, // kind
364-
14, // start pc
365-
14, // end pc
366-
7, // context level
367-
7, // index
368-
7, // start token pos
369-
7, // end token pos
370-
7, // decl token pos
371-
};
372-
#endif
373-
374358
void KernelBytecodeDisassembler::Disassemble(const Function& function) {
375359
#if !defined(PRODUCT)
376360
ASSERT(function.HasBytecode());
@@ -416,61 +400,11 @@ void KernelBytecodeDisassembler::Disassemble(const Function& function) {
416400

417401
if (bytecode.HasLocalVariablesInfo()) {
418402
#if !defined(DART_PRECOMPILED_RUNTIME)
419-
auto& name = String::Handle(zone);
420-
auto& type = AbstractType::Handle(zone);
421403
THR_Print("Local variable information for function '%s' {\n",
422404
function_fullname);
423-
// "*" in a printf format specifier tells it to read the field width from
424-
// the printf argument list.
425-
THR_Print(
426-
" %*s %*s %*s %*s %*s %*s %*s %*s name\n",
427-
kLocalVariableColumnWidths[0], "kind", kLocalVariableColumnWidths[1],
428-
"start pc", kLocalVariableColumnWidths[2], "end pc",
429-
kLocalVariableColumnWidths[3], "ctx", kLocalVariableColumnWidths[4],
430-
"index", kLocalVariableColumnWidths[5], "start",
431-
kLocalVariableColumnWidths[6], "end", kLocalVariableColumnWidths[7],
432-
"decl");
433-
bytecode::BytecodeLocalVariablesIterator iter(zone, bytecode);
434-
while (iter.MoveNext()) {
435-
THR_Print(" %*s %-#*" Px "", kLocalVariableColumnWidths[0],
436-
iter.KindName(), kLocalVariableColumnWidths[1],
437-
base + iter.StartPC());
438-
if (iter.IsVariableDeclaration() || iter.IsScope()) {
439-
THR_Print(" %-#*" Px "", kLocalVariableColumnWidths[2],
440-
base + iter.EndPC());
441-
} else {
442-
THR_Print(" %*s", kLocalVariableColumnWidths[2], "");
443-
}
444-
if (iter.IsScope()) {
445-
THR_Print(" %*" Pd "", kLocalVariableColumnWidths[3],
446-
iter.ContextLevel());
447-
} else {
448-
THR_Print(" %*s", kLocalVariableColumnWidths[3], "");
449-
}
450-
if (iter.IsContextVariable() || iter.IsVariableDeclaration()) {
451-
THR_Print(" %*" Pd "", kLocalVariableColumnWidths[4], iter.Index());
452-
} else {
453-
THR_Print(" %*s", kLocalVariableColumnWidths[4], "");
454-
}
455-
if (iter.IsVariableDeclaration() || iter.IsScope()) {
456-
THR_Print(" %*s %*s", kLocalVariableColumnWidths[5],
457-
iter.StartTokenPos().ToCString(),
458-
kLocalVariableColumnWidths[6],
459-
iter.EndTokenPos().ToCString());
460-
461-
} else {
462-
THR_Print(" %*s %*s", kLocalVariableColumnWidths[5], "",
463-
kLocalVariableColumnWidths[6], "");
464-
}
465-
if (iter.IsVariableDeclaration()) {
466-
name = iter.Name();
467-
type = iter.Type();
468-
THR_Print(" %*s %s: %s%s", kLocalVariableColumnWidths[7],
469-
iter.DeclarationTokenPos().ToCString(), name.ToCString(),
470-
type.ToCString(), iter.IsCaptured() ? " (captured)" : "");
471-
}
472-
THR_Print("\n");
473-
}
405+
ZoneTextBuffer buffer(zone);
406+
bytecode.WriteLocalVariablesInfo(zone, &buffer);
407+
THR_Print("%s", buffer.buffer());
474408
THR_Print("}\n");
475409
#else
476410
UNREACHABLE();

runtime/vm/debugger.cc

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "vm/timeline.h"
4141
#include "vm/token_position.h"
4242
#include "vm/visitor.h"
43+
#include "vm/zone_text_buffer.h"
4344

4445
#if !defined(DART_PRECOMPILED_RUNTIME)
4546
#include "vm/deopt_instructions.h"
@@ -629,18 +630,21 @@ bool ActivationFrame::IsDebuggable() const {
629630
return Debugger::IsDebuggable(function());
630631
}
631632

632-
void ActivationFrame::PrintDescriptorsError(const char* message) {
633-
OS::PrintErr("Bad descriptors: %s\n", message);
633+
void ActivationFrame::PrintContextLevelError(const char* message) {
634+
OS::PrintErr("Cannot locate context level: %s\n", message);
634635
OS::PrintErr("function %s\n", function().ToQualifiedCString());
635636
OS::PrintErr("pc_ %" Px "\n", pc_);
636637
OS::PrintErr("deopt_id_ %" Px "\n", deopt_id_);
637638
OS::PrintErr("context_level_ %" Px "\n", context_level_);
638639
OS::PrintErr("token_pos_ %s\n", token_pos_.ToCString());
639640
if (IsInterpreted()) {
640641
#if defined(DART_DYNAMIC_MODULES)
641-
DisassembleToStdout formatter;
642-
bytecode().Disassemble(&formatter);
643-
OS::PrintErr("%s\n", var_descriptors_.ToCString());
642+
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
643+
Zone* const zone = Thread::Current()->zone();
644+
ZoneTextBuffer buffer(zone);
645+
bytecode().WriteLocalVariablesInfo(zone, &buffer);
646+
OS::PrintErr("%s\n", buffer.buffer());
647+
#endif
644648
#else
645649
UNREACHABLE();
646650
#endif
@@ -677,7 +681,7 @@ intptr_t ActivationFrame::ContextLevel() {
677681
while (local_vars.MoveNext()) {
678682
if (local_vars.IsScope()) {
679683
if (local_vars.StartPC() <= pc_offset &&
680-
pc_offset < local_vars.EndPC()) {
684+
pc_offset <= local_vars.EndPC()) {
681685
DEBUG_ASSERT(!found || local_vars.StartPC() > closest_start);
682686
found = true;
683687
context_level_ = local_vars.ContextLevel();
@@ -689,6 +693,10 @@ intptr_t ActivationFrame::ContextLevel() {
689693
}
690694
}
691695
}
696+
if (!found) {
697+
PrintContextLevelError(
698+
"No Scope local variable info for the current PC");
699+
}
692700
#else
693701
UNREACHABLE();
694702
#endif
@@ -698,7 +706,7 @@ intptr_t ActivationFrame::ContextLevel() {
698706
// We store the deopt ids as real token positions.
699707
intptr_t deopt_id = DeoptId();
700708
if (deopt_id == DeoptId::kNone) {
701-
PrintDescriptorsError("Missing deopt id");
709+
PrintContextLevelError("Missing deopt id");
702710
}
703711
const TokenPosition to_compare = TokenPosition::Deserialize(deopt_id);
704712
for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
@@ -712,9 +720,10 @@ intptr_t ActivationFrame::ContextLevel() {
712720
break;
713721
}
714722
}
715-
}
716-
if (!found) {
717-
PrintDescriptorsError("Missing context level in var descriptors");
723+
if (!found) {
724+
PrintContextLevelError(
725+
"No ContextLevel var descriptor that contains the deopt id");
726+
}
718727
}
719728
ASSERT(context_level_ >= 0);
720729
}

runtime/vm/debugger.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ class ActivationFrame : public ZoneAllocated {
423423
void PrintContextMismatchError(intptr_t ctx_slot,
424424
intptr_t frame_ctx_level,
425425
intptr_t var_ctx_level);
426-
void PrintDescriptorsError(const char* message);
426+
void PrintContextLevelError(const char* message);
427427

428428
intptr_t TryIndex();
429429
intptr_t DeoptId();

runtime/vm/object.cc

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19389,6 +19389,86 @@ LocalVarDescriptorsPtr Bytecode::GetLocalVarDescriptors() const {
1938919389
UNREACHABLE();
1939019390
#endif
1939119391
}
19392+
19393+
#if defined(DART_DYNAMIC_MODULES)
19394+
static const int kLocalVariableKindMaxWidth = strlen(
19395+
bytecode::BytecodeLocalVariablesIterator::kKindNames
19396+
[bytecode::BytecodeLocalVariablesIterator::kVariableDeclaration]);
19397+
19398+
static const int kLocalVariableColumnWidths[] = {
19399+
kLocalVariableKindMaxWidth, // kind
19400+
14, // start pc
19401+
14, // end pc
19402+
7, // context level
19403+
7, // index
19404+
7, // start token pos
19405+
7, // end token pos
19406+
7, // decl token pos
19407+
};
19408+
#endif
19409+
19410+
void Bytecode::WriteLocalVariablesInfo(Zone* zone,
19411+
BaseTextBuffer* buffer) const {
19412+
#if defined(DART_DYNAMIC_MODULES)
19413+
if (!HasLocalVariablesInfo()) return;
19414+
19415+
// "*" in a printf format specifier tells it to read the field width from
19416+
// the printf argument list.
19417+
buffer->Printf(
19418+
" %*s %*s %*s %*s %*s %*s %*s %*s name\n", kLocalVariableColumnWidths[0],
19419+
"kind", kLocalVariableColumnWidths[1], "start pc",
19420+
kLocalVariableColumnWidths[2], "end pc", kLocalVariableColumnWidths[3],
19421+
"ctx", kLocalVariableColumnWidths[4], "index",
19422+
kLocalVariableColumnWidths[5], "start", kLocalVariableColumnWidths[6],
19423+
"end", kLocalVariableColumnWidths[7], "decl");
19424+
auto& name = String::Handle(zone);
19425+
auto& type = AbstractType::Handle(zone);
19426+
const uword base = PayloadStart();
19427+
bytecode::BytecodeLocalVariablesIterator iter(zone, *this);
19428+
while (iter.MoveNext()) {
19429+
buffer->Printf(" %*s %-#*" Px "", kLocalVariableColumnWidths[0],
19430+
iter.KindName(), kLocalVariableColumnWidths[1],
19431+
base + iter.StartPC());
19432+
if (iter.IsVariableDeclaration() || iter.IsScope()) {
19433+
buffer->Printf(" %-#*" Px "", kLocalVariableColumnWidths[2],
19434+
base + iter.EndPC());
19435+
} else {
19436+
buffer->Printf(" %*s", kLocalVariableColumnWidths[2], "");
19437+
}
19438+
if (iter.IsScope()) {
19439+
buffer->Printf(" %*" Pd "", kLocalVariableColumnWidths[3],
19440+
iter.ContextLevel());
19441+
} else {
19442+
buffer->Printf(" %*s", kLocalVariableColumnWidths[3], "");
19443+
}
19444+
if (iter.IsContextVariable() || iter.IsVariableDeclaration()) {
19445+
buffer->Printf(" %*" Pd "", kLocalVariableColumnWidths[4], iter.Index());
19446+
} else {
19447+
buffer->Printf(" %*s", kLocalVariableColumnWidths[4], "");
19448+
}
19449+
if (iter.IsVariableDeclaration() || iter.IsScope()) {
19450+
buffer->Printf(" %*s %*s", kLocalVariableColumnWidths[5],
19451+
iter.StartTokenPos().ToCString(),
19452+
kLocalVariableColumnWidths[6],
19453+
iter.EndTokenPos().ToCString());
19454+
19455+
} else {
19456+
buffer->Printf(" %*s %*s", kLocalVariableColumnWidths[5], "",
19457+
kLocalVariableColumnWidths[6], "");
19458+
}
19459+
if (iter.IsVariableDeclaration()) {
19460+
name = iter.Name();
19461+
type = iter.Type();
19462+
buffer->Printf(" %*s %s: %s%s", kLocalVariableColumnWidths[7],
19463+
iter.DeclarationTokenPos().ToCString(), name.ToCString(),
19464+
type.ToCString(), iter.IsCaptured() ? " (captured)" : "");
19465+
}
19466+
buffer->AddString("\n");
19467+
}
19468+
#else
19469+
UNREACHABLE();
19470+
#endif
19471+
}
1939219472
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
1939319473

1939419474
const char* Bytecode::ToCString() const {

runtime/vm/object.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7610,6 +7610,8 @@ class Bytecode : public Object {
76107610
untag()->set_var_descriptors<std::memory_order_release>(value.ptr());
76117611
}
76127612

7613+
void WriteLocalVariablesInfo(Zone* zone, BaseTextBuffer* buffer) const;
7614+
76137615
// Will compute local var descriptors if necessary.
76147616
LocalVarDescriptorsPtr GetLocalVarDescriptors() const;
76157617
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)

0 commit comments

Comments
 (0)