display globals in the debugger; display vars found in failing line
This commit is contained in:
parent
b02cafe672
commit
40ed7b960f
|
@ -12194,6 +12194,14 @@
|
||||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||||
},
|
},
|
||||||
|
"typedarray-to-buffer": {
|
||||||
|
"version": "3.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
|
||||||
|
"integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
|
||||||
|
"requires": {
|
||||||
|
"is-typedarray": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ua-parser-js": {
|
"ua-parser-js": {
|
||||||
"version": "0.7.18",
|
"version": "0.7.18",
|
||||||
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz",
|
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz",
|
||||||
|
@ -12924,19 +12932,8 @@
|
||||||
"integrity": "sha512-wAnENuZx75T5ZSrT2De2LOaUuPf2yRjq1VfcbD7+Zd79F3DZZLBJcPyCNVQ1U0fAXt0wfgCKl7sVw5pffqR9Bw==",
|
"integrity": "sha512-wAnENuZx75T5ZSrT2De2LOaUuPf2yRjq1VfcbD7+Zd79F3DZZLBJcPyCNVQ1U0fAXt0wfgCKl7sVw5pffqR9Bw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"underscore": "1.8.3",
|
"underscore": "1.8.3",
|
||||||
"web3-core-helpers": "1.0.0-beta.36"
|
"web3-core-helpers": "1.0.0-beta.36",
|
||||||
},
|
"websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2"
|
||||||
"dependencies": {
|
|
||||||
"websocket": {
|
|
||||||
"version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2",
|
|
||||||
"from": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2",
|
|
||||||
"requires": {
|
|
||||||
"debug": "^2.2.0",
|
|
||||||
"nan": "^2.3.3",
|
|
||||||
"typedarray-to-buffer": "^3.1.2",
|
|
||||||
"yaeti": "^0.0.6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web3-shh": {
|
"web3-shh": {
|
||||||
|
@ -13374,6 +13371,16 @@
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"websocket": {
|
||||||
|
"version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2",
|
||||||
|
"from": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible",
|
||||||
|
"requires": {
|
||||||
|
"debug": "^2.2.0",
|
||||||
|
"nan": "^2.3.3",
|
||||||
|
"typedarray-to-buffer": "^3.1.2",
|
||||||
|
"yaeti": "^0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"websocket-driver": {
|
"websocket-driver": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
|
||||||
|
@ -13604,6 +13611,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
|
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
|
||||||
},
|
},
|
||||||
|
"yaeti": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
|
||||||
|
"integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
|
||||||
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
|
||||||
|
|
|
@ -64,7 +64,7 @@ class ContractDebugger extends Component {
|
||||||
<Col>
|
<Col>
|
||||||
<br /><strong>Scopes</strong>
|
<br /><strong>Scopes</strong>
|
||||||
<div>
|
<div>
|
||||||
<ReactJson src={{locals: this.props.debuggerInfo.locals, contract: this.props.debuggerInfo.globals}} theme="monokai" sortKeys={true} name={false} collapse={1} />
|
<ReactJson src={{locals: this.props.debuggerInfo.locals, contract: this.props.debuggerInfo.contract, globals: this.props.debuggerInfo.globals}} theme="monokai" sortKeys={true} name={false} collapse={1} style={{"overflow-x": "auto"}} shouldCollapse={(field) => { return (field.name === 'globals') }} />
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
@ -293,6 +293,10 @@ class BlockchainConnector {
|
||||||
self.getBlock(blockNumber, cb);
|
self.getBlock(blockNumber, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.events.setCommandHandler("blockchain:block:byHash", function(blockHash, cb) {
|
||||||
|
self.getBlock(blockHash, cb);
|
||||||
|
});
|
||||||
|
|
||||||
this.events.setCommandHandler("blockchain:gasPrice", function(cb) {
|
this.events.setCommandHandler("blockchain:gasPrice", function(cb) {
|
||||||
self.getGasPrice(cb);
|
self.getGasPrice(cb);
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,9 +58,21 @@ class DebuggerManager {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
function startDebug(next) {
|
function startDebug(next) {
|
||||||
|
let debuggerData = {}
|
||||||
|
cmd_line.events.on("locals", (data) => {
|
||||||
|
debuggerData.locals = self.simplifyDebuggerVars(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
cmd_line.events.on("globals", (data) => {
|
||||||
|
debuggerData.contract = self.simplifyDebuggerVars(data)
|
||||||
|
})
|
||||||
|
|
||||||
cmd_line.startDebug(txHash, filename, () => {
|
cmd_line.startDebug(txHash, filename, () => {
|
||||||
cmd_line.events.on("source", () => {
|
cmd_line.events.on("source", () => {
|
||||||
outputCb(cmd_line.getSource())
|
let lines = cmd_line.getSource()
|
||||||
|
// TODO: this is a bit of a hack
|
||||||
|
let line = lines.filter((x) => x.indexOf("=>") === 0)[0];
|
||||||
|
outputCb(lines, line, debuggerData)
|
||||||
})
|
})
|
||||||
|
|
||||||
let total_size = cmd_line.getTraceLength()
|
let total_size = cmd_line.getTraceLength()
|
||||||
|
@ -73,6 +85,19 @@ class DebuggerManager {
|
||||||
], () => {
|
], () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is duplicated in debugger/index.js
|
||||||
|
simplifyDebuggerVars(data) {
|
||||||
|
let new_data = {};
|
||||||
|
|
||||||
|
for (let key in data) {
|
||||||
|
let field = data[key];
|
||||||
|
new_data[`${key} (${field.type})`] = field.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_data
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = DebuggerManager;
|
module.exports = DebuggerManager;
|
||||||
|
|
|
@ -30,15 +30,54 @@ class TransactionDebugger {
|
||||||
|
|
||||||
self.embark.logger.info("Transaction failed");
|
self.embark.logger.info("Transaction failed");
|
||||||
|
|
||||||
self.debugger_manager.getLastLine(tx.transactionHash, contract.filename, (lines) => {
|
self.debugger_manager.getLastLine(tx.transactionHash, contract.filename, (lines, line, known_vars) => {
|
||||||
lines.forEach((line) => {
|
lines.forEach((line) => {
|
||||||
self.embark.logger.error(line)
|
self.embark.logger.error(line)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self.find_vars_in_line(tx.transactionHash, line, known_vars, (found_vars) => {
|
||||||
|
if (!found_vars) return
|
||||||
|
self.embark.logger.info("vars:")
|
||||||
|
found_vars.forEach((variable) => {
|
||||||
|
self.embark.logger.info(`${variable.name}: ${variable.value}`)
|
||||||
|
})
|
||||||
|
});
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
find_vars_in_line(txHash, line, known_vars, cb) {
|
||||||
|
let found_vars = [];
|
||||||
|
this.getGlobals(txHash, (err, globals) => {
|
||||||
|
if (err) return cb([]);
|
||||||
|
for (let variable in globals) {
|
||||||
|
let value = globals[variable]
|
||||||
|
if (line.indexOf(variable) >= 0) {
|
||||||
|
found_vars.push({name: variable, value: value});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let variable in known_vars.locals) {
|
||||||
|
let value = known_vars.locals[variable];
|
||||||
|
let variable_name = variable.split(' ')[0]
|
||||||
|
if (line.indexOf(variable_name) >= 0) {
|
||||||
|
found_vars.push({name: variable, value: value});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let variable in known_vars.contract) {
|
||||||
|
let value = known_vars.contract[variable];
|
||||||
|
let variable_name = variable.split(' ')[0]
|
||||||
|
if (line.indexOf(variable_name) >= 0) {
|
||||||
|
found_vars.push({name: variable, value: value});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cb(found_vars);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
listentoAPI() {
|
listentoAPI() {
|
||||||
this.debuggerData = {}
|
this.debuggerData = {}
|
||||||
this.apiDebugger = false
|
this.apiDebugger = false
|
||||||
|
@ -54,10 +93,13 @@ class TransactionDebugger {
|
||||||
|
|
||||||
let filename = contract.filename
|
let filename = contract.filename
|
||||||
|
|
||||||
this.debuggerData = {}
|
|
||||||
this.apiDebugger = this.debugger_manager.createDebuggerSession(txHash, filename, () => {
|
this.apiDebugger = this.debugger_manager.createDebuggerSession(txHash, filename, () => {
|
||||||
|
this.getGlobals(txHash, (err, globals) => {
|
||||||
|
if (err) return res.send({ok: false});
|
||||||
|
this.debuggerData.globals = globals;
|
||||||
|
res.send({ok :true})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
res.send({ok :true})
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -98,13 +140,13 @@ class TransactionDebugger {
|
||||||
ws.send(JSON.stringify(this.debuggerData), () => {})
|
ws.send(JSON.stringify(this.debuggerData), () => {})
|
||||||
})
|
})
|
||||||
|
|
||||||
this.apiDebugger.events.on("locals", (data) => {
|
this.apiDebugger.events.on("locals", (data) => {
|
||||||
this.debuggerData.locals = this.simplifyDebuggerVars(data)
|
this.debuggerData.locals = this.simplifyDebuggerVars(data)
|
||||||
ws.send(JSON.stringify(this.debuggerData), () => {})
|
ws.send(JSON.stringify(this.debuggerData), () => {})
|
||||||
})
|
});
|
||||||
|
|
||||||
this.apiDebugger.events.on("globals", (data) => {
|
this.apiDebugger.events.on("globals", (data) => {
|
||||||
this.debuggerData.globals = this.simplifyDebuggerVars(data)
|
this.debuggerData.contract = this.simplifyDebuggerVars(data)
|
||||||
ws.send(JSON.stringify(this.debuggerData), () => {})
|
ws.send(JSON.stringify(this.debuggerData), () => {})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -124,6 +166,7 @@ class TransactionDebugger {
|
||||||
listenToCommands() {
|
listenToCommands() {
|
||||||
const self = this
|
const self = this
|
||||||
this.cmdDebugger = false
|
this.cmdDebugger = false
|
||||||
|
this.currentCmdTxHash = ""
|
||||||
|
|
||||||
this.embark.registerConsoleCommand((cmd, _options) => {
|
this.embark.registerConsoleCommand((cmd, _options) => {
|
||||||
let cmdName = cmd.split(" ")[0]
|
let cmdName = cmd.split(" ")[0]
|
||||||
|
@ -138,6 +181,7 @@ class TransactionDebugger {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let filename = contract.filename
|
let filename = contract.filename
|
||||||
|
self.currentCmdTxHash = txHash
|
||||||
self.cmdDebugger = self.debugger_manager.createDebuggerSession(txHash, filename, () => {
|
self.cmdDebugger = self.debugger_manager.createDebuggerSession(txHash, filename, () => {
|
||||||
self.cmdDebugger.getSource().forEach((line) => {
|
self.cmdDebugger.getSource().forEach((line) => {
|
||||||
console.dir(line)
|
console.dir(line)
|
||||||
|
@ -146,6 +190,7 @@ class TransactionDebugger {
|
||||||
});
|
});
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
self.currentCmdTxHash = self.last_tx
|
||||||
let filename = self.tx_tracker[self.last_tx].contract.filename
|
let filename = self.tx_tracker[self.last_tx].contract.filename
|
||||||
self.cmdDebugger = self.debugger_manager.createDebuggerSession(self.last_tx, filename, () => {
|
self.cmdDebugger = self.debugger_manager.createDebuggerSession(self.last_tx, filename, () => {
|
||||||
self.cmdDebugger.getSource().forEach((line) => {
|
self.cmdDebugger.getSource().forEach((line) => {
|
||||||
|
@ -205,8 +250,46 @@ class TransactionDebugger {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.embark.registerConsoleCommand((cmd, _options) => {
|
||||||
|
return {
|
||||||
|
match: () => (cmd === 'var all' || cmd === 'v a' || cmd === 'va'),
|
||||||
|
process: (cb) => {
|
||||||
|
|
||||||
|
self.getGlobals((err, globals) => {
|
||||||
|
if (err) return self.embark.logger.error(err);
|
||||||
|
console.dir(globals);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getGlobals(txHash, cb) {
|
||||||
|
let globals = {}
|
||||||
|
this.embark.events.request("blockchain:getTransaction", txHash, (err, tx) => {
|
||||||
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
this.embark.events.request("blockchain:block:byHash", tx.blockHash, (err, block) => {
|
||||||
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
globals["block.blockHash"] = tx.blockHash;
|
||||||
|
globals["block.number"] = tx.blockNumber;
|
||||||
|
globals["block.coinbase"] = block.miner;
|
||||||
|
globals["block.difficulty"] = block.difficulty;
|
||||||
|
globals["block.gaslimit"] = block.gasLimit;
|
||||||
|
globals["block.timestamp"] = block.timestamp;
|
||||||
|
globals["msg.sender"] = tx.from;
|
||||||
|
globals["msg.gas"] = tx.gas;
|
||||||
|
globals["msg.gasPrice"] = tx.gasPrice;
|
||||||
|
globals["msg.value"] = tx.value;
|
||||||
|
globals["now"] = block.timestamp;
|
||||||
|
|
||||||
|
cb(null, globals);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = TransactionDebugger
|
module.exports = TransactionDebugger
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -11,7 +11,8 @@ contract SimpleStorage {
|
||||||
|
|
||||||
function set(uint x) public {
|
function set(uint x) public {
|
||||||
storedData = x;
|
storedData = x;
|
||||||
require(msg.sender == 0x0);
|
require(msg.sender == owner);
|
||||||
|
//require(msg.sender == 0x0);
|
||||||
storedData = x + 2;
|
storedData = x + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,11 @@ contract SimpleStorageTest is Ownable {
|
||||||
storedData = x + 2;
|
storedData = x + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function set2(uint x) public onlyOwner {
|
||||||
|
storedData = x;
|
||||||
|
storedData = x + 2;
|
||||||
|
}
|
||||||
|
|
||||||
function test(uint x) public {
|
function test(uint x) public {
|
||||||
uint value = 1;
|
uint value = 1;
|
||||||
assembly {
|
assembly {
|
||||||
|
|
Loading…
Reference in New Issue