Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Have debugger skip anything called from a generated source while stepping #6138

Merged
merged 4 commits into from Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions packages/debugger/lib/controller/sagas/index.js
Expand Up @@ -78,16 +78,20 @@ function* advance(action) {
*/
function* stepNext() {
const starting = yield select(controller.current.location);
const isStartingGenerated = yield select(
controller.current.isAnyFrameGenerated
);
const allowInternal = yield select(controller.stepIntoInternalSources);

let upcoming, finished;
let upcoming, finished, isUpcomingGenerated;

do {
// advance at least once step
yield* advance();

// and check the next source range
upcoming = yield select(controller.current.location);
isUpcomingGenerated = yield select(controller.current.isAnyFrameGenerated);

finished = yield select(controller.current.trace.finished);

Expand All @@ -98,8 +102,8 @@ function* stepNext() {
//don't stop on an internal source unless allowInternal is on or
//we started in an internal source
(!allowInternal &&
upcoming.source.internal &&
!starting.source.internal) ||
(upcoming.source.internal || isUpcomingGenerated) &&
!(starting.source.internal || isStartingGenerated)) ||
upcoming.sourceRange.length === 0 ||
upcoming.source.id === undefined ||
(upcoming.node && isDeliberatelySkippedNodeType(upcoming.node)) ||
Expand Down
19 changes: 19 additions & 0 deletions packages/debugger/lib/controller/selectors/index.js
Expand Up @@ -7,6 +7,7 @@ import * as Codec from "@truffle/codec";

import evm from "lib/evm/selectors";
import sourcemapping from "lib/sourcemapping/selectors";
import stacktrace from "lib/stacktrace/selectors";
import data from "lib/data/selectors";
import trace from "lib/trace/selectors";

Expand Down Expand Up @@ -137,6 +138,24 @@ const controller = createSelectorTree({
)
},

/**
* controller.current.callstack
*/
callstack: createLeaf([stacktrace.current.callstack.preupdated], identity),

/**
* controller.current.isAnyFrameGenerated
*
* This selector checks whether there are any generated sources
* stackframes on the callstack. We should regard ourselves
* as still inside a generated source until there are none.
* (We only consider generated sources here, not other sorts of internal
* sources, to prevent potential problems.)
*/
isAnyFrameGenerated: createLeaf(["./callstack"], callstack =>
callstack.some(frame => frame.sourceIsGenerated)
),

/**
* controller.current.trace
*/
Expand Down
11 changes: 9 additions & 2 deletions packages/debugger/lib/stacktrace/actions/index.js
@@ -1,11 +1,18 @@
export const JUMP_IN = "STACKTRACE_JUMP_IN";
export function jumpIn(location, functionNode, contractNode, sourceIsInternal) {
export function jumpIn(
location,
functionNode,
contractNode,
sourceIsInternal,
sourceIsGenerated
) {
return {
type: JUMP_IN,
location,
functionNode,
contractNode,
sourceIsInternal
sourceIsInternal,
sourceIsGenerated
};
}

Expand Down
11 changes: 9 additions & 2 deletions packages/debugger/lib/stacktrace/reducers.js
Expand Up @@ -10,7 +10,13 @@ function callstack(state = [], action) {
let newFrame;
switch (action.type) {
case actions.JUMP_IN:
const { location, functionNode, contractNode, sourceIsInternal } = action;
const {
location,
functionNode,
contractNode,
sourceIsInternal,
sourceIsGenerated
} = action;
newFrame = {
type: "internal",
calledFromLocation: location,
Expand All @@ -27,7 +33,8 @@ function callstack(state = [], action) {
? contractNode.name
: undefined,
combineWithNextInternal: false,
sourceIsInternal
sourceIsInternal,
sourceIsGenerated
//note we don't currently account for getters because currently
//we can't; fallback, receive, constructors, & modifiers also remain
//unaccounted for at present
Expand Down
6 changes: 5 additions & 1 deletion packages/debugger/lib/stacktrace/sagas/index.js
Expand Up @@ -63,12 +63,16 @@ function* stacktraceSaga() {
const nextLocation = yield select(stacktrace.next.location);
const nextParent = yield select(stacktrace.next.contractNode);
const nextSourceIsInternal = yield select(stacktrace.next.sourceIsInternal);
const nextSourceIsGenerated = yield select(
stacktrace.next.sourceIsGenerated
);
yield put(
actions.jumpIn(
currentLocation,
nextLocation.node,
nextParent,
nextSourceIsInternal
nextSourceIsInternal,
nextSourceIsGenerated
)
);
positionUpdated = true;
Expand Down
39 changes: 31 additions & 8 deletions packages/debugger/lib/stacktrace/selectors/index.js
Expand Up @@ -111,6 +111,15 @@ function createMultistepSelectors(stepSelector) {
source => source.id === undefined || source.internal
),

/**
* .sourceIsGenerated
* only specifically generated sources, not unmapped code or anything!
*/
sourceIsGenerated: createLeaf(
["./location/source"],
source => source.internal
),

/**
* .strippedLocation
*/
Expand Down Expand Up @@ -156,9 +165,27 @@ let stacktrace = createSelectorTree({
*/
current: {
/**
* stacktrace.current.callstack
* stacktrace.current.callstack (namespace)
*/
callstack: createLeaf(["/state"], state => state.proc.callstack),
callstack: {
/**
* stacktrace.current.callstack (selector)
*/
_: createLeaf(["/state"], state => state.proc.callstack),

/**
* stacktrace.current.callstack.preupdated
*/
preupdated: createLeaf(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably warrants a note about what "preupdated" means

["./_", "/current/returnCounter"],
(callstack, returnCounter) =>
popNWhere(
callstack,
returnCounter,
frame => frame.type === "external"
)
)
},

/**
* stacktrace.current.returnCounter
Expand Down Expand Up @@ -398,18 +425,14 @@ let stacktrace = createSelectorTree({
*/
report: createLeaf(
[
"./callstack",
"./callstack/preupdated",
"./returnCounter",
"./lastPosition",
"/current/strippedLocation"
],
(callstack, returnCounter, lastPosition, currentLocation) =>
generateReport(
popNWhere(
callstack,
returnCounter,
frame => frame.type === "external"
),
callstack,
currentLocation || lastPosition,
null,
undefined
Expand Down