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
5c1c75f0
Unverified
Commit
5c1c75f0
authored
Nov 28, 2018
by
yann300
Committed by
GitHub
Nov 28, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #995 from ethereum/move_debugger
move debugger logic from remix-ide to remix-debug
parents
8846f8d4
c4bb550d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
669 additions
and
44 deletions
+669
-44
index.js
remix-debug/index.js
+2
-0
Ethdebugger.js
remix-debug/src/Ethdebugger.js
+4
-42
SolidityLocals.js
remix-debug/src/debugger/SolidityLocals.js
+65
-0
VmDebugger.js
remix-debug/src/debugger/VmDebugger.js
+241
-0
debugger.js
remix-debug/src/debugger/debugger.js
+131
-0
solidityState.js
remix-debug/src/debugger/solidityState.js
+80
-0
stepManager.js
remix-debug/src/debugger/stepManager.js
+145
-0
util.js
remix-debug/src/solidity-decoder/types/util.js
+0
-1
tests.js
remix-debug/test/tests.js
+0
-0
execution-context.js
remix-lib/src/execution/execution-context.js
+1
-1
No files found.
remix-debug/index.js
View file @
5c1c75f0
'use strict'
var
EthDebugger
=
require
(
'./src/Ethdebugger'
)
var
TransactionDebugger
=
require
(
'./src/debugger/debugger'
)
var
StorageViewer
=
require
(
'./src/storage/storageViewer'
)
var
StorageResolver
=
require
(
'./src/storage/storageResolver'
)
...
...
@@ -19,6 +20,7 @@ var BreakpointManager = remixLib.code.BreakpointManager
*/
module
.
exports
=
{
EthDebugger
:
EthDebugger
,
TransactionDebugger
:
TransactionDebugger
,
/**
* constructor
*
...
...
remix-debug/src/Ethdebugger.js
View file @
5c1c75f0
...
...
@@ -13,11 +13,7 @@ var remixLib = require('remix-lib')
var
TraceManager
=
remixLib
.
trace
.
TraceManager
var
CodeManager
=
remixLib
.
code
.
CodeManager
var
traceHelper
=
remixLib
.
helpers
.
trace
var
init
=
remixLib
.
init
var
executionContext
=
remixLib
.
execution
.
executionContext
var
EventManager
=
remixLib
.
EventManager
var
Web3Providers
=
remixLib
.
vm
.
Web3Providers
var
DummyProvider
=
remixLib
.
vm
.
DummyProvider
/**
* Ethdebugger is a wrapper around a few classes that helps debugging a transaction
...
...
@@ -36,17 +32,12 @@ function Ethdebugger (opts) {
this
.
opts
=
opts
||
{}
if
(
!
this
.
opts
.
compilationResult
)
this
.
opts
.
compilationResult
=
()
=>
{
return
null
}
this
.
executionContext
=
opts
.
executionContext
||
executionContext
this
.
web3
=
opts
.
web3
||
this
.
executionContext
.
web3
this
.
web3
=
opts
.
web3
this
.
event
=
new
EventManager
()
this
.
tx
this
.
web3Providers
=
new
Web3Providers
()
this
.
addProvider
(
'DUMMYWEB3'
,
new
DummyProvider
())
this
.
switchProvider
(
'DUMMYWEB3'
)
this
.
traceManager
=
new
TraceManager
({
web3
:
this
.
web3
})
this
.
codeManager
=
new
CodeManager
(
this
.
traceManager
)
this
.
solidityProxy
=
new
SolidityProxy
(
this
.
traceManager
,
this
.
codeManager
)
...
...
@@ -163,39 +154,10 @@ Ethdebugger.prototype.storageViewAt = function (step, address) {
address
:
address
},
this
.
storageResolver
,
this
.
traceManager
)
}
/* set env */
Ethdebugger
.
prototype
.
web3
=
function
()
{
return
this
.
web3
}
Ethdebugger
.
prototype
.
addProvider
=
function
(
type
,
obj
)
{
this
.
web3Providers
.
addProvider
(
type
,
obj
)
this
.
event
.
trigger
(
'providerAdded'
,
[
type
])
}
Ethdebugger
.
prototype
.
switchProvider
=
function
(
type
)
{
var
self
=
this
this
.
web3Providers
.
get
(
type
,
function
(
error
,
obj
)
{
if
(
error
)
{
console
.
log
(
'provider '
+
type
+
' not defined'
)
}
else
{
self
.
web3
=
obj
self
.
setManagers
()
// self.traceManager.web3 = self.web3
self
.
executionContext
.
detectNetwork
((
error
,
network
)
=>
{
if
(
error
||
!
network
)
{
self
.
web3Debug
=
obj
self
.
web3
=
obj
}
else
{
var
webDebugNode
=
init
.
web3DebugNode
(
network
.
name
)
self
.
web3Debug
=
!
webDebugNode
?
obj
:
webDebugNode
self
.
web3
=
!
webDebugNode
?
obj
:
webDebugNode
}
self
.
setManagers
()
})
self
.
event
.
trigger
(
'providerChanged'
,
[
type
])
}
})
Ethdebugger
.
prototype
.
updateWeb3
=
function
(
web3
)
{
this
.
web3
=
web3
this
.
setManagers
()
}
Ethdebugger
.
prototype
.
debug
=
function
(
tx
)
{
...
...
remix-debug/src/debugger/SolidityLocals.js
0 → 100644
View file @
5c1c75f0
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
localDecoder
=
require
(
'../solidity-decoder/localDecoder'
)
var
StorageViewer
=
require
(
'../storage/storageViewer'
)
class
DebuggerSolidityLocals
{
constructor
(
tx
,
_stepManager
,
_traceManager
,
_internalTreeCall
)
{
this
.
event
=
new
EventManager
()
this
.
stepManager
=
_stepManager
this
.
internalTreeCall
=
_internalTreeCall
this
.
storageResolver
=
null
this
.
traceManager
=
_traceManager
this
.
tx
=
tx
}
init
(
sourceLocation
)
{
const
self
=
this
var
decodeTimeout
=
null
if
(
!
this
.
storageResolver
)
{
return
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
'storage not ready'
])
}
if
(
decodeTimeout
)
{
window
.
clearTimeout
(
decodeTimeout
)
}
self
.
event
.
trigger
(
'solidityLocalsUpdating'
)
decodeTimeout
=
setTimeout
(
function
()
{
self
.
decode
(
sourceLocation
)
},
500
)
}
decode
(
sourceLocation
)
{
const
self
=
this
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
''
])
self
.
traceManager
.
waterfall
([
self
.
traceManager
.
getStackAt
,
self
.
traceManager
.
getMemoryAt
,
self
.
traceManager
.
getCurrentCalledAddressAt
],
self
.
stepManager
.
currentStepIndex
,
(
error
,
result
)
=>
{
if
(
error
)
{
return
console
.
log
(
error
)
}
var
stack
=
result
[
0
].
value
var
memory
=
result
[
1
].
value
try
{
var
storageViewer
=
new
StorageViewer
({
stepIndex
:
self
.
stepManager
.
currentStepIndex
,
tx
:
self
.
tx
,
address
:
result
[
2
].
value
},
self
.
storageResolver
,
self
.
traceManager
)
localDecoder
.
solidityLocals
(
self
.
stepManager
.
currentStepIndex
,
self
.
internalTreeCall
,
stack
,
memory
,
storageViewer
,
sourceLocation
).
then
((
locals
)
=>
{
if
(
!
locals
.
error
)
{
self
.
event
.
trigger
(
'solidityLocals'
,
[
locals
])
}
if
(
!
Object
.
keys
(
locals
).
length
)
{
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
'no locals'
])
}
})
}
catch
(
e
)
{
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
e
.
message
])
}
})
}
}
module
.
exports
=
DebuggerSolidityLocals
remix-debug/src/debugger/VmDebugger.js
0 → 100644
View file @
5c1c75f0
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
ui
=
remixLib
.
helpers
.
ui
var
StorageResolver
=
require
(
'../storage/storageResolver'
)
var
StorageViewer
=
require
(
'../storage/storageViewer'
)
var
DebuggerSolidityState
=
require
(
'./solidityState'
)
var
DebuggerSolidityLocals
=
require
(
'./solidityLocals'
)
class
VmDebuggerLogic
{
constructor
(
_debugger
,
tx
,
_stepManager
,
_traceManager
,
_codeManager
,
_solidityProxy
,
_callTree
)
{
this
.
event
=
new
EventManager
()
this
.
debugger
=
_debugger
this
.
stepManager
=
_stepManager
this
.
_traceManager
=
_traceManager
this
.
_codeManager
=
_codeManager
this
.
_solidityProxy
=
_solidityProxy
this
.
_callTree
=
_callTree
this
.
storageResolver
=
null
this
.
tx
=
tx
this
.
debuggerSolidityState
=
new
DebuggerSolidityState
(
tx
,
_stepManager
,
_traceManager
,
_codeManager
,
_solidityProxy
)
this
.
debuggerSolidityLocals
=
new
DebuggerSolidityLocals
(
tx
,
_stepManager
,
_traceManager
,
_callTree
)
}
start
()
{
this
.
listenToEvents
()
this
.
listenToCodeManagerEvents
()
this
.
listenToTraceManagerEvents
()
this
.
listenToFullStorageChanges
()
this
.
listenToNewChanges
()
this
.
listenToSolidityStateEvents
()
this
.
listenToSolidityLocalsEvents
()
}
listenToEvents
()
{
const
self
=
this
this
.
debugger
.
event
.
register
(
'traceUnloaded'
,
function
()
{
self
.
event
.
trigger
(
'traceUnloaded'
)
})
this
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
function
()
{
self
.
event
.
trigger
(
'newTraceLoaded'
)
})
}
listenToCodeManagerEvents
()
{
const
self
=
this
this
.
_codeManager
.
event
.
register
(
'changed'
,
function
(
code
,
address
,
index
)
{
self
.
event
.
trigger
(
'codeManagerChanged'
,
[
code
,
address
,
index
])
})
}
listenToTraceManagerEvents
()
{
const
self
=
this
this
.
event
.
register
(
'indexChanged'
,
this
,
function
(
index
)
{
if
(
index
<
0
)
return
if
(
self
.
stepManager
.
currentStepIndex
!==
index
)
return
self
.
event
.
trigger
(
'indexUpdate'
,
[
index
])
self
.
_traceManager
.
getCallDataAt
(
index
,
function
(
error
,
calldata
)
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerCallDataUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceManagerCallDataUpdate'
,
[
calldata
])
}
})
self
.
_traceManager
.
getMemoryAt
(
index
,
function
(
error
,
memory
)
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerMemoryUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceManagerMemoryUpdate'
,
[
ui
.
formatMemory
(
memory
,
16
)])
}
})
self
.
_traceManager
.
getCallStackAt
(
index
,
function
(
error
,
callstack
)
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerCallStackUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceManagerCallStackUpdate'
,
[
callstack
])
}
})
self
.
_traceManager
.
getStackAt
(
index
,
function
(
error
,
callstack
)
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerStackUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceManagerStackUpdate'
,
[
callstack
])
}
})
self
.
_traceManager
.
getCurrentCalledAddressAt
(
index
,
(
error
,
address
)
=>
{
if
(
error
)
return
if
(
!
self
.
storageResolver
)
return
var
storageViewer
=
new
StorageViewer
({
stepIndex
:
self
.
stepManager
.
currentStepIndex
,
tx
:
self
.
tx
,
address
:
address
},
self
.
storageResolver
,
self
.
_traceManager
)
storageViewer
.
storageRange
((
error
,
storage
)
=>
{
if
(
error
)
{
console
.
log
(
error
)
self
.
event
.
trigger
(
'traceManagerStorageUpdate'
,
[{}])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
var
header
=
storageViewer
.
isComplete
(
address
)
?
'completely loaded'
:
'partially loaded...'
self
.
event
.
trigger
(
'traceManagerStorageUpdate'
,
[
storage
,
header
])
}
})
})
self
.
_traceManager
.
getCurrentStep
(
index
,
function
(
error
,
step
)
{
self
.
event
.
trigger
(
'traceCurrentStepUpdate'
,
[
error
,
step
])
})
self
.
_traceManager
.
getMemExpand
(
index
,
function
(
error
,
addmem
)
{
self
.
event
.
trigger
(
'traceMemExpandUpdate'
,
[
error
,
addmem
])
})
self
.
_traceManager
.
getStepCost
(
index
,
function
(
error
,
gas
)
{
self
.
event
.
trigger
(
'traceStepCostUpdate'
,
[
error
,
gas
])
})
self
.
_traceManager
.
getCurrentCalledAddressAt
(
index
,
function
(
error
,
address
)
{
self
.
event
.
trigger
(
'traceCurrentCalledAddressAtUpdate'
,
[
error
,
address
])
})
self
.
_traceManager
.
getRemainingGas
(
index
,
function
(
error
,
remaining
)
{
self
.
event
.
trigger
(
'traceRemainingGasUpdate'
,
[
error
,
remaining
])
})
self
.
_traceManager
.
getReturnValue
(
index
,
function
(
error
,
returnValue
)
{
if
(
error
)
{
self
.
event
.
trigger
(
'traceReturnValueUpdate'
,
[[
error
]])
}
else
if
(
self
.
stepManager
.
currentStepIndex
===
index
)
{
self
.
event
.
trigger
(
'traceReturnValueUpdate'
,
[[
returnValue
]])
}
})
})
}
listenToFullStorageChanges
()
{
const
self
=
this
this
.
address
=
[]
this
.
traceLength
=
0
self
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
function
(
length
)
{
self
.
_traceManager
.
getAddresses
(
function
(
error
,
addresses
)
{
if
(
error
)
return
self
.
event
.
trigger
(
'traceAddressesUpdate'
,
[
addresses
])
self
.
addresses
=
addresses
})
self
.
_traceManager
.
getLength
(
function
(
error
,
length
)
{
if
(
error
)
return
self
.
event
.
trigger
(
'traceLengthUpdate'
,
[
length
])
self
.
traceLength
=
length
})
})
self
.
debugger
.
event
.
register
(
'indexChanged'
,
this
,
function
(
index
)
{
if
(
index
<
0
)
return
if
(
self
.
stepManager
.
currentStepIndex
!==
index
)
return
if
(
!
self
.
storageResolver
)
return
if
(
index
!==
self
.
traceLength
-
1
)
{
return
self
.
event
.
trigger
(
'traceLengthUpdate'
,
[{}])
}
var
storageJSON
=
{}
for
(
var
k
in
self
.
addresses
)
{
var
address
=
self
.
addresses
[
k
]
var
storageViewer
=
new
StorageViewer
({
stepIndex
:
self
.
stepManager
.
currentStepIndex
,
tx
:
self
.
tx
,
address
:
address
},
self
.
storageResolver
,
self
.
_traceManager
)
storageViewer
.
storageRange
(
function
(
error
,
result
)
{
if
(
!
error
)
{
storageJSON
[
address
]
=
result
self
.
event
.
trigger
(
'traceLengthUpdate'
,
[
storageJSON
])
}
})
}
})
}
listenToNewChanges
()
{
const
self
=
this
self
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
this
,
function
()
{
self
.
storageResolver
=
new
StorageResolver
({
web3
:
self
.
debugger
.
web3
})
self
.
debuggerSolidityState
.
storageResolver
=
self
.
storageResolver
self
.
debuggerSolidityLocals
.
storageResolver
=
self
.
storageResolver
self
.
event
.
trigger
(
'newTrace'
,
[])
})
self
.
debugger
.
event
.
register
(
'callTreeReady'
,
function
()
{
if
(
self
.
debugger
.
callTree
.
reducedTrace
.
length
)
{
return
self
.
event
.
trigger
(
'newCallTree'
,
[])
}
})
}
listenToSolidityStateEvents
()
{
const
self
=
this
this
.
event
.
register
(
'indexChanged'
,
this
.
debuggerSolidityState
.
init
.
bind
(
this
.
debuggerSolidityState
))
this
.
debuggerSolidityState
.
event
.
register
(
'solidityState'
,
function
(
state
)
{
self
.
event
.
trigger
(
'solidityState'
,
[
state
])
})
this
.
debuggerSolidityState
.
event
.
register
(
'solidityStateMessage'
,
function
(
message
)
{
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
message
])
})
this
.
debuggerSolidityState
.
event
.
register
(
'solidityStateUpdating'
,
function
()
{
self
.
event
.
trigger
(
'solidityStateUpdating'
,
[])
})
this
.
event
.
register
(
'traceUnloaded'
,
this
.
debuggerSolidityState
.
reset
.
bind
(
this
.
debuggerSolidityState
))
this
.
event
.
register
(
'newTraceLoaded'
,
this
.
debuggerSolidityState
.
reset
.
bind
(
this
.
debuggerSolidityState
))
}
listenToSolidityLocalsEvents
()
{
const
self
=
this
this
.
event
.
register
(
'sourceLocationChanged'
,
this
.
debuggerSolidityLocals
.
init
.
bind
(
this
.
debuggerSolidityLocals
))
this
.
debuggerSolidityLocals
.
event
.
register
(
'solidityLocals'
,
function
(
state
)
{
self
.
event
.
trigger
(
'solidityLocals'
,
[
state
])
})
this
.
debuggerSolidityLocals
.
event
.
register
(
'solidityLocalsMessage'
,
function
(
message
)
{
self
.
event
.
trigger
(
'solidityLocalsMessage'
,
[
message
])
})
this
.
debuggerSolidityLocals
.
event
.
register
(
'solidityLocalsUpdating'
,
function
()
{
self
.
event
.
trigger
(
'solidityLocalsUpdating'
,
[])
})
this
.
debuggerSolidityLocals
.
event
.
register
(
'traceReturnValueUpdate'
,
function
(
data
,
header
)
{
self
.
event
.
trigger
(
'traceReturnValueUpdate'
,
[
data
,
header
])
})
}
}
module
.
exports
=
VmDebuggerLogic
remix-debug/src/debugger/debugger.js
0 → 100644
View file @
5c1c75f0
'use strict'
var
Ethdebugger
=
require
(
'../Ethdebugger'
)
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
traceHelper
=
remixLib
.
helpers
.
trace
var
StepManager
=
require
(
'./stepManager'
)
var
VmDebuggerLogic
=
require
(
'./VmDebugger'
)
function
Debugger
(
options
)
{
var
self
=
this
this
.
event
=
new
EventManager
()
this
.
offsetToLineColumnConverter
=
options
.
offsetToLineColumnConverter
this
.
compiler
=
options
.
compiler
this
.
debugger
=
new
Ethdebugger
({
web3
:
options
.
web3
,
compilationResult
:
()
=>
{
var
compilationResult
=
this
.
compiler
.
lastCompilationResult
if
(
compilationResult
)
{
return
compilationResult
.
data
}
return
null
}
})
this
.
breakPointManager
=
new
remixLib
.
code
.
BreakpointManager
(
this
.
debugger
,
(
sourceLocation
)
=>
{
return
self
.
offsetToLineColumnConverter
.
offsetToLineColumn
(
sourceLocation
,
sourceLocation
.
file
,
this
.
compiler
.
lastCompilationResult
.
source
.
sources
,
this
.
compiler
.
lastCompilationResult
.
data
.
sources
)
},
(
step
)
=>
{
self
.
event
.
trigger
(
'breakpointStep'
,
[
step
])
})
this
.
debugger
.
setBreakpointManager
(
this
.
breakPointManager
)
this
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
this
,
function
()
{
self
.
event
.
trigger
(
'debuggerStatus'
,
[
true
])
})
this
.
debugger
.
event
.
register
(
'traceUnloaded'
,
this
,
function
()
{
self
.
event
.
trigger
(
'debuggerStatus'
,
[
false
])
})
this
.
event
.
register
(
'breakpointStep'
,
function
(
step
)
{
self
.
step_manager
.
jumpTo
(
step
)
})
}
Debugger
.
prototype
.
registerAndHighlightCodeItem
=
function
(
index
)
{
const
self
=
this
// register selected code item, highlight the corresponding source location
if
(
!
self
.
compiler
.
lastCompilationResult
)
return
self
.
debugger
.
traceManager
.
getCurrentCalledAddressAt
(
index
,
(
error
,
address
)
=>
{
if
(
error
)
return
console
.
log
(
error
)
self
.
debugger
.
callTree
.
sourceLocationTracker
.
getSourceLocationFromVMTraceIndex
(
address
,
index
,
self
.
compiler
.
lastCompilationResult
.
data
.
contracts
,
function
(
error
,
rawLocation
)
{
if
(
!
error
&&
self
.
compiler
.
lastCompilationResult
&&
self
.
compiler
.
lastCompilationResult
.
data
)
{
var
lineColumnPos
=
self
.
offsetToLineColumnConverter
.
offsetToLineColumn
(
rawLocation
,
rawLocation
.
file
,
self
.
compiler
.
lastCompilationResult
.
source
.
sources
,
self
.
compiler
.
lastCompilationResult
.
data
.
sources
)
self
.
event
.
trigger
(
'newSourceLocation'
,
[
lineColumnPos
,
rawLocation
])
}
else
{
self
.
event
.
trigger
(
'newSourceLocation'
,
[
null
])
}
})
})
}
Debugger
.
prototype
.
updateWeb3
=
function
(
web3
)
{
this
.
debugger
.
web3
=
web3
}
Debugger
.
prototype
.
debug
=
function
(
blockNumber
,
txNumber
,
tx
,
loadingCb
)
{
const
self
=
this
let
web3
=
this
.
debugger
.
web3
if
(
this
.
debugger
.
traceManager
.
isLoading
)
{
return
}
if
(
tx
)
{
if
(
!
tx
.
to
)
{
tx
.
to
=
traceHelper
.
contractCreationToken
(
'0'
)
}
return
self
.
debugTx
(
tx
,
loadingCb
)
}
try
{
if
(
txNumber
.
indexOf
(
'0x'
)
!==
-
1
)
{
return
web3
.
eth
.
getTransaction
(
txNumber
,
function
(
_error
,
result
)
{
let
tx
=
result
self
.
debugTx
(
tx
,
loadingCb
)
})
}
web3
.
eth
.
getTransactionFromBlock
(
blockNumber
,
txNumber
,
function
(
_error
,
result
)
{
let
tx
=
result
self
.
debugTx
(
tx
,
loadingCb
)
})
}
catch
(
e
)
{
console
.
error
(
e
.
message
)
}
}
Debugger
.
prototype
.
debugTx
=
function
(
tx
,
loadingCb
)
{
const
self
=
this
this
.
step_manager
=
new
StepManager
(
this
.
debugger
,
this
.
debugger
.
traceManager
)
this
.
debugger
.
codeManager
.
event
.
register
(
'changed'
,
this
,
(
code
,
address
,
instIndex
)
=>
{
self
.
debugger
.
callTree
.
sourceLocationTracker
.
getSourceLocationFromVMTraceIndex
(
address
,
this
.
step_manager
.
currentStepIndex
,
this
.
debugger
.
solidityProxy
.
contracts
,
(
error
,
sourceLocation
)
=>
{
if
(
!
error
)
{
self
.
vmDebuggerLogic
.
event
.
trigger
(
'sourceLocationChanged'
,
[
sourceLocation
])
}
})
})
this
.
vmDebuggerLogic
=
new
VmDebuggerLogic
(
this
.
debugger
,
tx
,
this
.
step_manager
,
this
.
debugger
.
traceManager
,
this
.
debugger
.
codeManager
,
this
.
debugger
.
solidityProxy
,
this
.
debugger
.
callTree
)
this
.
step_manager
.
event
.
register
(
'stepChanged'
,
this
,
function
(
stepIndex
)
{
self
.
debugger
.
codeManager
.
resolveStep
(
stepIndex
,
tx
)
self
.
step_manager
.
event
.
trigger
(
'indexChanged'
,
[
stepIndex
])
self
.
vmDebuggerLogic
.
event
.
trigger
(
'indexChanged'
,
[
stepIndex
])
self
.
registerAndHighlightCodeItem
(
stepIndex
)
})
loadingCb
()
this
.
debugger
.
debug
(
tx
)
}
Debugger
.
prototype
.
unload
=
function
()
{
this
.
debugger
.
unLoad
()
this
.
event
.
trigger
(
'debuggerUnloaded'
)
}
module
.
exports
=
Debugger
remix-debug/src/debugger/solidityState.js
0 → 100644
View file @
5c1c75f0
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
var
stateDecoder
=
require
(
'../solidity-decoder/stateDecoder'
)
var
StorageViewer
=
require
(
'../storage/storageViewer'
)
class
DebuggerSolidityState
{
constructor
(
tx
,
_stepManager
,
_traceManager
,
_codeManager
,
_solidityProxy
)
{
this
.
event
=
new
EventManager
()
this
.
storageResolver
=
null
this
.
stepManager
=
_stepManager
this
.
traceManager
=
_traceManager
this
.
codeManager
=
_codeManager
this
.
solidityProxy
=
_solidityProxy
this
.
stateVariablesByAddresses
=
{}
this
.
tx
=
tx
}
init
(
index
)
{
var
self
=
this
var
decodeTimeout
=
null
if
(
index
<
0
)
{
return
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
'invalid step index'
])
}
if
(
self
.
stepManager
.
currentStepIndex
!==
index
)
return
if
(
!
self
.
solidityProxy
.
loaded
())
{
return
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
'invalid step index'
])
}
if
(
!
self
.
storageResolver
)
{
return
}
if
(
decodeTimeout
)
{
window
.
clearTimeout
(
decodeTimeout
)
}
self
.
event
.
trigger
(
'solidityStateUpdating'
)
decodeTimeout
=
setTimeout
(
function
()
{
self
.
decode
(
index
)
},
500
)
}
reset
()
{
this
.
stateVariablesByAddresses
=
{}
}
decode
(
index
)
{
const
self
=
this
self
.
traceManager
.
getCurrentCalledAddressAt
(
self
.
stepManager
.
currentStepIndex
,
function
(
error
,
address
)
{
if
(
error
)
{
return
self
.
event
.
trigger
(
'solidityState'
,
[{}])
}
if
(
self
.
stateVariablesByAddresses
[
address
])
{
return
self
.
extractStateVariables
(
self
.
stateVariablesByAddresses
[
address
],
address
)
}
self
.
solidityProxy
.
extractStateVariablesAt
(
index
,
function
(
error
,
stateVars
)
{
if
(
error
)
{
return
self
.
event
.
trigger
(
'solidityState'
,
[{}])
}
self
.
stateVariablesByAddresses
[
address
]
=
stateVars
self
.
extractStateVariables
(
stateVars
,
address
)
})
})
}
extractStateVariables
(
stateVars
,
address
)
{
const
self
=
this
var
storageViewer
=
new
StorageViewer
({
stepIndex
:
self
.
stepManager
.
currentStepIndex
,
tx
:
self
.
tx
,
address
:
address
},
self
.
storageResolver
,
self
.
traceManager
)
stateDecoder
.
decodeState
(
stateVars
,
storageViewer
).
then
((
result
)
=>
{
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
''
])
if
(
result
.
error
)
{
return
self
.
event
.
trigger
(
'solidityStateMessage'
,
[
result
.
error
])
}
self
.
event
.
trigger
(
'solidityState'
,
[
result
])
})
}
}
module
.
exports
=
DebuggerSolidityState
remix-debug/src/debugger/stepManager.js
0 → 100644
View file @
5c1c75f0
var
remixLib
=
require
(
'remix-lib'
)
var
EventManager
=
remixLib
.
EventManager
class
DebuggerStepManager
{
constructor
(
_debugger
,
traceManager
)
{
this
.
event
=
new
EventManager
()
this
.
debugger
=
_debugger
this
.
traceManager
=
traceManager
this
.
currentStepIndex
=
0
this
.
traceLength
=
0
this
.
revertionPoint
=
null
this
.
listenToEvents
()
}
listenToEvents
()
{
const
self
=
this
this
.
debugger
.
event
.
register
(
'newTraceLoaded'
,
this
,
function
()
{
self
.
traceManager
.
getLength
(
function
(
error
,
newLength
)
{
if
(
error
)
{
return
console
.
log
(
error
)
}
if
(
self
.
traceLength
!==
newLength
)
{
self
.
event
.
trigger
(
'traceLengthChanged'
,
[
newLength
])
self
.
traceLength
=
newLength
}
self
.
jumpTo
(
0
)
})
})
this
.
debugger
.
callTree
.
event
.
register
(
'callTreeReady'
,
()
=>
{
if
(
self
.
debugger
.
callTree
.
functionCallStack
.
length
)
{
self
.
jumpTo
(
self
.
debugger
.
callTree
.
functionCallStack
[
0
])
}
})
this
.
event
.
register
(
'indexChanged'
,
this
,
(
index
)
=>
{
if
(
index
<
0
)
return
if
(
self
.
currentStepIndex
!==
index
)
return
self
.
traceManager
.
buildCallPath
(
index
,
(
error
,
callsPath
)
=>
{
if
(
error
)
{
console
.
log
(
error
)
return
self
.
event
.
trigger
(
'revertWarning'
,
[
''
])
}
self
.
currentCall
=
callsPath
[
callsPath
.
length
-
1
]
if
(
self
.
currentCall
.
reverted
)
{
let
revertedReason
=
self
.
currentCall
.
outofgas
?
'outofgas'
:
''
self
.
revertionPoint
=
self
.
currentCall
.
return
return
self
.
event
.
trigger
(
'revertWarning'
,
[
revertedReason
])
}
for
(
var
k
=
callsPath
.
length
-
2
;
k
>=
0
;
k
--
)
{
var
parent
=
callsPath
[
k
]
if
(
!
parent
.
reverted
)
continue
self
.
revertionPoint
=
parent
.
return
self
.
event
.
trigger
(
'revertWarning'
,
[
'parenthasthrown'
])
}
self
.
event
.
trigger
(
'revertWarning'
,
[
''
])
})
})
}
triggerStepChanged
(
step
)
{
const
self
=
this
this
.
traceManager
.
getLength
(
function
(
error
,
length
)
{
let
stepState
=
'valid'
if
(
error
)
{
stepState
=
'invalid'
}
else
if
(
step
<=
0
)
{
stepState
=
'initial'
}
else
if
(
step
>=
length
-
1
)
{
stepState
=
'end'
}
let
jumpOutDisabled
=
(
step
===
self
.
traceManager
.
findStepOut
(
step
))
self
.
event
.
trigger
(
'stepChanged'
,
[
step
,
stepState
,
jumpOutDisabled
])
})
}
stepIntoBack
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
currentStepIndex
-
1
this
.
currentStepIndex
=
step
if
(
!
this
.
traceManager
.
inRange
(
step
))
{
return
}
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
stepIntoForward
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
currentStepIndex
+
1
this
.
currentStepIndex
=
step
if
(
!
this
.
traceManager
.
inRange
(
step
))
{
return
}
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
stepOverBack
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
traceManager
.
findStepOverBack
(
this
.
currentStepIndex
)
this
.
currentStepIndex
=
step
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
stepOverForward
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
traceManager
.
findStepOverForward
(
this
.
currentStepIndex
)
this
.
currentStepIndex
=
step
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
jumpOut
()
{
if
(
!
this
.
traceManager
.
isLoaded
())
return
var
step
=
this
.
traceManager
.
findStepOut
(
this
.
currentStepIndex
)
this
.
currentStepIndex
=
step
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
jumpTo
(
step
)
{
if
(
!
this
.
traceManager
.
inRange
(
step
))
return
this
.
currentStepIndex
=
step
this
.
event
.
trigger
(
'stepChanged'
,
[
step
])
}
jumpToException
()
{
this
.
jumpTo
(
this
.
revertionPoint
)
}
jumpNextBreakpoint
()
{
this
.
debugger
.
breakpointManager
.
jumpNextBreakpoint
(
this
.
currentStepIndex
,
true
)
}
jumpPreviousBreakpoint
()
{
this
.
debugger
.
breakpointManager
.
jumpPreviousBreakpoint
(
this
.
currentStepIndex
,
true
)
}
}
module
.
exports
=
DebuggerStepManager
remix-debug/src/solidity-decoder/types/util.js
View file @
5c1c75f0
...
...
@@ -67,7 +67,6 @@ async function extractHexValue (location, storageResolver, byteLength) {
try
{
slotvalue
=
await
readFromStorage
(
location
.
slot
,
storageResolver
)
}
catch
(
e
)
{
console
.
log
(
e
)
return
'0x'
}
return
extractHexByteSlice
(
slotvalue
,
byteLength
,
location
.
offset
)
...
...
remix-debug/test/tests.js
View file @
5c1c75f0
This diff is collapsed.
Click to expand it.
remix-lib/src/execution/execution-context.js
View file @
5c1c75f0
...
...
@@ -67,7 +67,7 @@ var vm = new EthJSVM({
vm
.
stateManager
=
stateManager
vm
.
blockchain
=
stateManager
.
blockchain
vm
.
trie
=
stateManager
.
trie
vm
.
stateManager
.
checkpoint
()
vm
.
stateManager
.
checkpoint
(
()
=>
{}
)
var
web3VM
=
new
Web3VMProvider
()
web3VM
.
setVM
(
vm
)
...
...
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