Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
244295e4
Unverified
Commit
244295e4
authored
Jun 23, 2020
by
yann300
Committed by
GitHub
Jun 23, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1467 from ethereum/stackTrace
API for returning the function stack trace by vm trace index
parents
162f5bb2
672a1ad3
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
85 additions
and
26 deletions
+85
-26
package.json
package.json
+1
-1
VmDebugger.js
remix-debug/src/debugger/VmDebugger.js
+2
-0
internalCallTree.js
remix-debug/src/solidity-decoder/internalCallTree.js
+45
-9
intLocal.js
remix-debug/test/decoder/contracts/intLocal.js
+8
-8
int.js
remix-debug/test/decoder/localsTests/int.js
+29
-8
No files found.
package.json
View file @
244295e4
...
...
@@ -7,7 +7,7 @@
"scripts"
:
{
"diff"
:
"lerna diff"
,
"updated"
:
"lerna updated"
,
"bootstrap"
:
"
npm run build-ts-packages; lerna bootstrap
"
,
"bootstrap"
:
"
lerna bootstrap; npm run build-ts-packages
"
,
"build-ts-packages"
:
"lerna run --scope 'remix-analyzer' --scope 'remix-astwalker' --scope 'remix-solidity' --scope 'remix-tests' --scope 'remix-url-resolver' build"
,
"publish"
:
"npm run build-ts-packages; lerna publish"
,
"release"
:
"lerna bootstrap; lerna publish;"
,
...
...
remix-debug/src/debugger/VmDebugger.js
View file @
244295e4
...
...
@@ -58,6 +58,8 @@ class VmDebuggerLogic {
this
.
event
.
trigger
(
'indexUpdate'
,
[
index
])
this
.
event
.
trigger
(
'functionsStackUpdate'
,
[
this
.
_callTree
.
retrieveFunctionsStack
(
index
)])
this
.
_traceManager
.
getCallDataAt
(
index
,
(
error
,
calldata
)
=>
{
if
(
error
)
{
// console.log(error)
...
...
remix-debug/src/solidity-decoder/internalCallTree.js
View file @
244295e4
...
...
@@ -66,6 +66,7 @@ class InternalCallTree {
*/
this
.
sourceLocationTracker
.
clearCache
()
this
.
functionCallStack
=
[]
this
.
functionDefinitionsByScope
=
{}
this
.
scopeStarts
=
{}
this
.
variableDeclarationByFile
=
{}
this
.
functionDefinitionByFile
=
{}
...
...
@@ -79,21 +80,49 @@ class InternalCallTree {
* @param {Int} vmtraceIndex - index on the vm trace
*/
findScope
(
vmtraceIndex
)
{
const
scopes
=
Object
.
keys
(
this
.
scopeStarts
)
if
(
!
scopes
.
length
)
{
return
null
}
let
scopeId
=
util
.
findLowerBoundValue
(
vmtraceIndex
,
scopes
)
scopeId
=
this
.
scopeStarts
[
scopeId
]
let
scopeId
=
this
.
findScopeId
(
vmtraceIndex
)
if
(
scopeId
!==
''
&&
!
scopeId
)
return
null
let
scope
=
this
.
scopes
[
scopeId
]
while
(
scope
.
lastStep
&&
scope
.
lastStep
<
vmtraceIndex
&&
scope
.
firstStep
>
0
)
{
const
matched
=
scopeId
.
match
(
/
(
.
\d
|
\d)
$/
)
scopeId
=
scopeId
.
replace
(
matched
[
1
],
''
)
scopeId
=
this
.
parentScope
(
scopeId
)
scope
=
this
.
scopes
[
scopeId
]
}
return
scope
}
parentScope
(
scopeId
)
{
const
matched
=
scopeId
.
match
(
/
(
.
\d
|
\d)
$/
)
return
scopeId
.
replace
(
matched
[
1
],
''
)
}
findScopeId
(
vmtraceIndex
)
{
const
scopes
=
Object
.
keys
(
this
.
scopeStarts
)
if
(
!
scopes
.
length
)
return
null
const
scopeStart
=
util
.
findLowerBoundValue
(
vmtraceIndex
,
scopes
)
return
this
.
scopeStarts
[
scopeStart
]
}
retrieveFunctionsStack
(
vmtraceIndex
)
{
let
scope
=
this
.
findScope
(
vmtraceIndex
)
if
(
!
scope
)
return
[]
let
scopeId
=
this
.
scopeStarts
[
scope
.
firstStep
]
let
functions
=
[]
if
(
!
scopeId
)
return
functions
let
i
=
0
while
(
true
)
{
i
+=
1
if
(
i
>
1000
)
throw
new
Error
(
'retrieFunctionStack: recursion too deep'
)
let
functionDefinition
=
this
.
functionDefinitionsByScope
[
scopeId
]
if
(
functionDefinition
!==
undefined
)
{
functions
.
push
(
functionDefinition
)
}
let
parent
=
this
.
parentScope
(
scopeId
)
if
(
!
parent
)
break
else
scopeId
=
parent
}
return
functions
}
extractSourceLocation
(
step
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
this
.
traceManager
.
getCurrentCalledAddressAt
(
step
,
(
error
,
address
)
=>
{
...
...
@@ -220,6 +249,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
const
functionDefinition
=
resolveFunctionDefinition
(
tree
,
step
,
previousSourceLocation
)
if
(
functionDefinition
&&
(
newLocation
&&
traceHelper
.
isJumpDestInstruction
(
tree
.
traceManager
.
trace
[
step
-
1
])
||
functionDefinition
.
attributes
.
isConstructor
))
{
tree
.
functionCallStack
.
push
(
step
)
const
functionDefinitionAndInputs
=
{
functionDefinition
,
inputs
:
[]}
// means: the previous location was a function definition && JUMPDEST
// => we are at the beginning of the function and input/output are setup
tree
.
solidityProxy
.
contractNameAt
(
step
,
(
error
,
contractName
)
=>
{
// cached
...
...
@@ -240,7 +270,9 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
}
}
// input params
if
(
inputs
)
addParams
(
inputs
,
tree
,
scopeId
,
states
,
contractName
,
previousSourceLocation
,
stack
.
length
,
inputs
.
children
.
length
,
-
1
)
if
(
inputs
)
{
functionDefinitionAndInputs
.
inputs
=
addParams
(
inputs
,
tree
,
scopeId
,
states
,
contractName
,
previousSourceLocation
,
stack
.
length
,
inputs
.
children
.
length
,
-
1
)
}
// output params
if
(
outputs
)
addParams
(
outputs
,
tree
,
scopeId
,
states
,
contractName
,
previousSourceLocation
,
stack
.
length
,
0
,
1
)
}
...
...
@@ -248,6 +280,7 @@ function includeVariableDeclaration (tree, step, sourceLocation, scopeId, newLoc
})
}
})
tree
.
functionDefinitionsByScope
[
scopeId
]
=
functionDefinitionAndInputs
}
}
...
...
@@ -304,6 +337,7 @@ function extractFunctionDefinitions (ast, astWalker) {
}
function
addParams
(
parameterList
,
tree
,
scopeId
,
states
,
contractName
,
sourceLocation
,
stackLength
,
stackPosition
,
dir
)
{
let
params
=
[]
for
(
let
inputParam
in
parameterList
.
children
)
{
const
param
=
parameterList
.
children
[
inputParam
]
const
stackDepth
=
stackLength
+
(
dir
*
stackPosition
)
...
...
@@ -317,9 +351,11 @@ function addParams (parameterList, tree, scopeId, states, contractName, sourceLo
stackDepth
:
stackDepth
,
sourceLocation
:
sourceLocation
}
params
.
push
(
attributesName
)
}
stackPosition
+=
dir
}
return
params
}
module
.
exports
=
InternalCallTree
remix-debug/test/decoder/contracts/intLocal.js
View file @
244295e4
...
...
@@ -26,17 +26,17 @@ contract intLocal {
int256 i256 = 3434343;
int i = -32432423423;
int32 ishrink = 2;
level11();
level12();
level11();
level11(
123
);
level12(
12
);
level11(
123
);
}
function level11() public {
uint8 ui8 =
123
;
level12();
function level11(
uint8 foo
) public {
uint8 ui8 =
foo
;
level12(
12
);
}
function level12() public {
uint8 ui81 =
12
;
function level12(
uint8 asd
) public {
uint8 ui81 =
asd
;
}
}
`
}
remix-debug/test/decoder/localsTests/int.js
View file @
244295e4
...
...
@@ -37,14 +37,35 @@ module.exports = function (st, vm, privateKey, contractBytecode, compilationResu
})
callTree
.
event
.
register
(
'callTreeReady'
,
(
scopes
,
scopeStarts
)
=>
{
try
{
console
.
log
(
scopeStarts
)
let
functions1
=
callTree
.
retrieveFunctionsStack
(
102
)
let
functions2
=
callTree
.
retrieveFunctionsStack
(
115
)
let
functions3
=
callTree
.
retrieveFunctionsStack
(
13
)
st
.
equals
(
functions1
.
length
,
1
)
st
.
equals
(
functions2
.
length
,
2
)
st
.
equals
(
functions3
.
length
,
0
)
st
.
equals
(
Object
.
keys
(
functions1
[
0
])[
0
],
'functionDefinition'
)
st
.
equals
(
Object
.
keys
(
functions1
[
0
])[
1
],
'inputs'
)
st
.
equals
(
functions1
[
0
].
inputs
[
0
],
'foo'
)
st
.
equals
(
Object
.
keys
(
functions2
[
0
])[
0
],
'functionDefinition'
)
st
.
equals
(
Object
.
keys
(
functions2
[
0
])[
1
],
'inputs'
)
st
.
equals
(
Object
.
keys
(
functions2
[
1
])[
0
],
'functionDefinition'
)
st
.
equals
(
Object
.
keys
(
functions2
[
1
])[
1
],
'inputs'
)
st
.
equals
(
functions2
[
0
].
inputs
[
0
],
'asd'
)
st
.
equals
(
functions2
[
1
].
inputs
[
0
],
'foo'
)
st
.
equals
(
functions1
[
0
].
functionDefinition
.
attributes
.
name
,
'level11'
)
st
.
equals
(
functions2
[
0
].
functionDefinition
.
attributes
.
name
,
'level12'
)
st
.
equals
(
functions2
[
1
].
functionDefinition
.
attributes
.
name
,
'level11'
)
st
.
equals
(
scopeStarts
[
0
],
''
)
st
.
equals
(
scopeStarts
[
13
],
'1'
)
st
.
equals
(
scopeStarts
[
10
1
],
'2'
)
st
.
equals
(
scopeStarts
[
11
3
],
'2.1'
)
st
.
equals
(
scopeStarts
[
13
1
],
'3'
)
st
.
equals
(
scopeStarts
[
1
46
],
'4'
)
st
.
equals
(
scopeStarts
[
1
58
],
'4.1'
)
st
.
equals
(
scopeStarts
[
10
2
],
'2'
)
st
.
equals
(
scopeStarts
[
11
5
],
'2.1'
)
st
.
equals
(
scopeStarts
[
13
6
],
'3'
)
st
.
equals
(
scopeStarts
[
1
53
],
'4'
)
st
.
equals
(
scopeStarts
[
1
66
],
'4.1'
)
st
.
equals
(
scopes
[
''
].
locals
[
'ui8'
].
type
.
typeName
,
'uint8'
)
st
.
equals
(
scopes
[
''
].
locals
[
'ui16'
].
type
.
typeName
,
'uint16'
)
st
.
equals
(
scopes
[
''
].
locals
[
'ui32'
].
type
.
typeName
,
'uint32'
)
...
...
@@ -88,10 +109,10 @@ module.exports = function (st, vm, privateKey, contractBytecode, compilationResu
st
.
equals
(
locals
[
'ishrink'
].
value
,
'2'
)
})
helper
.
decodeLocals
(
st
,
10
5
,
traceManager
,
callTree
,
function
(
locals
)
{
helper
.
decodeLocals
(
st
,
10
6
,
traceManager
,
callTree
,
function
(
locals
)
{
try
{
st
.
equals
(
locals
[
'ui8'
].
value
,
'123'
)
st
.
equals
(
Object
.
keys
(
locals
).
length
,
1
)
st
.
equals
(
Object
.
keys
(
locals
).
length
,
2
)
}
catch
(
e
)
{
st
.
fail
(
e
.
message
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment