Skip to content

Commit 7e84681

Browse files
authored
Tracing checkpoint policy (#348)
* Add tracing checkpoint policy This option is configurable, this way you can choose when it sends data, for example: only after input primitives. Additionally, the data it sends can also be configured, for example: only send the program counter. * Fix comparison of integer expressions of different signedness * Refactor trace conditions to be inside checkpoint * Make force parameter const * Set default min_return_values to 0
1 parent e2f775b commit 7e84681

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

src/Debug/debugger.cpp

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ Debugger::Debugger(Channel *duplex) {
2525
this->checkpointInterval = 10;
2626
this->instructions_executed = 0;
2727
this->fidx_called = {};
28+
this->min_return_values = 0;
29+
this->checkpoint_state = nullptr;
30+
this->checkpoint_state_size = 0;
2831
this->remaining_instructions = -1;
2932
}
3033

@@ -965,11 +968,33 @@ void Debugger::inspect(Module *m, const uint16_t sizeStateArray,
965968
}
966969

967970
void Debugger::setSnapshotPolicy(Module *m, uint8_t *interruptData) {
968-
snapshotPolicy = SnapshotPolicy{*interruptData};
971+
uint8_t **data_ptr = &interruptData;
972+
if (*interruptData <= 2) {
973+
snapshotPolicy = SnapshotPolicy{*interruptData};
974+
min_return_values = 0;
975+
if (checkpoint_state) {
976+
free(checkpoint_state);
977+
}
978+
checkpoint_state = nullptr;
979+
checkpoint_state_size = 0;
980+
} else {
981+
snapshotPolicy = SnapshotPolicy::checkpointing;
982+
*data_ptr += 1;
983+
min_return_values = read_LEB_32(data_ptr);
984+
if (checkpoint_state) {
985+
free(checkpoint_state);
986+
}
987+
checkpoint_state_size = read_LEB_32(data_ptr);
988+
checkpoint_state = new uint8_t[checkpoint_state_size];
989+
for (uint32_t i = 0; i < checkpoint_state_size; i++) {
990+
checkpoint_state[i] = **data_ptr;
991+
*data_ptr += 1;
992+
}
993+
}
969994

970995
// Make a checkpoint when you first enable checkpointing
971996
if (snapshotPolicy == SnapshotPolicy::checkpointing) {
972-
uint8_t *ptr = interruptData + 1;
997+
uint8_t *ptr = *data_ptr + 1;
973998
checkpointInterval = read_B32(&ptr);
974999
checkpoint(m, true);
9751000
}
@@ -1016,11 +1041,24 @@ void Debugger::handleSnapshotPolicy(Module *m) {
10161041
}
10171042
}
10181043

1019-
void Debugger::checkpoint(Module *m, bool force) {
1044+
void Debugger::checkpoint(Module *m, const bool force) {
10201045
if (instructions_executed == 0 && !force) {
10211046
return;
10221047
}
10231048

1049+
if (min_return_values != 0) {
1050+
if (!fidx_called) {
1051+
// Tracing mode is on, but no primitive was called.
1052+
return;
1053+
}
1054+
1055+
const Type *type = m->functions[*fidx_called].type;
1056+
if (type->result_count < min_return_values) {
1057+
// Primitive was called but did not have the required return values.
1058+
return;
1059+
}
1060+
}
1061+
10241062
this->channel->write(R"(CHECKPOINT {"instructions_executed": %d, )",
10251063
instructions_executed);
10261064
if (fidx_called) {
@@ -1032,9 +1070,23 @@ void Debugger::checkpoint(Module *m, bool force) {
10321070
comma = true;
10331071
}
10341072
this->channel->write("], ");
1073+
1074+
// Return values:
1075+
this->channel->write(R"("returns": [)");
1076+
comma = false;
1077+
for (uint32_t i = 0; i < func_block.type->result_count; i++) {
1078+
channel->write("%s%d", comma ? ", " : "",
1079+
m->stack[m->sp - i].value.uint32);
1080+
comma = true;
1081+
}
1082+
this->channel->write("], ");
1083+
}
1084+
this->channel->write(R"("snapshot": )");
1085+
if (!checkpoint_state) {
1086+
snapshot(m);
1087+
} else {
1088+
inspect(m, checkpoint_state_size, checkpoint_state);
10351089
}
1036-
this->channel->write(R"("snapshot": )", instructions_executed);
1037-
snapshot(m);
10381090
this->channel->write("}\n");
10391091
instructions_executed = 0;
10401092
}

src/Debug/debugger.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ class Debugger {
138138
uint32_t instructions_executed; // #instructions since last checkpoint
139139
std::optional<uint32_t> fidx_called; // The primitive that was executed
140140
uint32_t prim_args[8]; // The arguments of the executed prim
141+
uint32_t min_return_values;
142+
uint32_t checkpoint_state_size;
143+
uint8_t *checkpoint_state;
141144

142145
// Continue for
143146
int32_t remaining_instructions;

0 commit comments

Comments
 (0)