Skip to content

Commit

Permalink
fix: 🐛 Fix bug that prevents breakpoints to be hit inside function de…
Browse files Browse the repository at this point in the history
…finitions (#7)

Custom gate definitions are defined with start position at `gate...` and end position at their closing `}`. Therefore, when putting a breakpoint at any location within those bounds, it was always attached to the function. Now, if a breakpoint would be attached to a function, we first check if it would fit better to one of the gates inside it.
  • Loading branch information
DRovara authored Aug 9, 2024
1 parent fa4a10a commit 5036680
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/backend/dd/DDSimDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,28 @@ Result ddsimSetBreakpoint(SimulationState* self, size_t desiredPosition,
const size_t start = ddsim->instructionStarts[i];
const size_t end = ddsim->instructionEnds[i];
if (desiredPosition >= start && desiredPosition <= end) {
if (ddsim->processedCode.substr(start, end - start).find("gate ") !=
std::string::npos) {
// Breakpoint may be located in a sub-gate of the gate definition.
for (auto j = i + 1; j < ddsim->instructionTypes.size(); j++) {
const size_t startSub = ddsim->instructionStarts[j];
const size_t endSub = ddsim->instructionEnds[j];
if (startSub > desiredPosition) {
break;
}
if (endSub >= desiredPosition) {
*targetInstruction = j;
ddsim->breakpoints.insert(j);
return OK;
}
if (ddsim->instructionTypes[j] == RETURN) {
break;
}
}
*targetInstruction = i;
ddsim->breakpoints.insert(i);
return OK;
}
*targetInstruction = i;
ddsim->breakpoints.insert(i);
return OK;
Expand Down
50 changes: 50 additions & 0 deletions test/test_simulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,56 @@ TEST_P(SimulationTest, RunSimulation) {
ASSERT_TRUE(state->isFinished(state));
}

TEST_P(SimulationTest, InGateDefinitionBreakpoints) {
const std::map<const std::string, std::vector<size_t>> breakpointPositions = {
{"complex-jumps", {86, 280, 411}}, {"failing-assertions", {}}};
const std::map<const std::string, std::vector<size_t>>
expectedBreakpointPositions = {{"complex-jumps", {2, 7, 11}},
{"failing-assertions", {}}};
const std::map<const std::string, std::vector<size_t>>
expectedBreakpointHits = {
{"complex-jumps", {2, 11, 7, 2, 11, 2, 11, 2, 11}},
{"failing-assertions", {}}};

for (size_t index = 0; index < breakpointPositions.at(GetParam()).size();
index++) {
const auto breakpoint = breakpointPositions.at(GetParam())[index];
size_t targetInstruction = 0;
ASSERT_EQ(state->setBreakpoint(state, breakpoint, &targetInstruction),
Result::OK)
<< "Failed to set breakpoint at instruction " << breakpoint << " in "
<< GetParam() << "\n";
ASSERT_EQ(targetInstruction,
expectedBreakpointPositions.at(GetParam())[index])
<< "Breakpoint set at wrong instruction for breakpoint " << breakpoint
<< " in " << GetParam() << "\n";
}

for (const auto instruction : expectedBreakpointHits.at(GetParam())) {
ASSERT_EQ(state->runSimulation(state), Result::OK)
<< "Failed to run simulation in " << GetParam() << "\n";
while (state->didAssertionFail(state)) {
ASSERT_EQ(state->runSimulation(state), Result::OK)
<< "Failed to run simulation in " << GetParam() << "\n";
}
ASSERT_EQ(state->getCurrentInstruction(state), instruction)
<< "Breakpoint not hit at expected instruction " << instruction
<< " in " << GetParam() << "\n";
ASSERT_TRUE(state->wasBreakpointHit(state));
}

ASSERT_EQ(state->clearBreakpoints(state), Result::OK)
<< "Failed to clear breakpoints in " << GetParam() << "\n";
ASSERT_EQ(state->runSimulationBackward(state), Result::OK);
ASSERT_FALSE(state->wasBreakpointHit(state))
<< "Breakpoint hit after clearing in " << GetParam() << "\n";
while (!state->isFinished(state)) {
ASSERT_EQ(state->runSimulation(state), Result::OK);
ASSERT_FALSE(state->wasBreakpointHit(state))
<< "Breakpoint hit after clearing in " << GetParam() << "\n";
}
}

INSTANTIATE_TEST_SUITE_P(StringParams, SimulationTest,
::testing::Values("complex-jumps",
"failing-assertions"));

0 comments on commit 5036680

Please sign in to comment.