New debugger
This commit is contained in:
		
							parent
							
								
									4fd267a778
								
							
						
					
					
						commit
						d0b31e2030
					
				| @ -7,108 +7,210 @@ import QtQuick.Controls.Styles 1.1 | ||||
| import Ethereum 1.0 | ||||
| 
 | ||||
| ApplicationWindow { | ||||
| 	id: debugWindow | ||||
| 	visible: false | ||||
| 	title: "Debugger" | ||||
| 	minimumWidth: 600 | ||||
| 	minimumHeight: 600 | ||||
| 	width: 800 | ||||
| 	height: 600 | ||||
|     visible: false | ||||
|     title: "Debugger" | ||||
|     minimumWidth: 1280 | ||||
|     minimumHeight: 900 | ||||
|     width: 1290 | ||||
|     height: 900 | ||||
| 
 | ||||
| 	SplitView { | ||||
| 		anchors.fill: parent | ||||
| 		property var asmModel: ListModel { | ||||
| 			id: asmModel | ||||
| 		} | ||||
| 		TableView { | ||||
| 			id: asmTableView | ||||
| 			width: 200 | ||||
| 			TableViewColumn{ role: "value" ; title: "" ; width: 100 } | ||||
| 			model: asmModel | ||||
| 		} | ||||
|     SplitView { | ||||
|         anchors.fill: parent | ||||
|         property var asmModel: ListModel { | ||||
|             id: asmModel | ||||
|         } | ||||
|         TableView { | ||||
|             id: asmTableView | ||||
|             width: 200 | ||||
|             TableViewColumn{ role: "value" ; title: "" ; width: 100 } | ||||
|             model: asmModel | ||||
|         } | ||||
| 
 | ||||
| 		Rectangle { | ||||
| 			anchors.left: asmTableView.right | ||||
| 			anchors.right: parent.right | ||||
| 			SplitView { | ||||
| 				orientation: Qt.Vertical | ||||
| 				anchors.fill: parent | ||||
|         Rectangle { | ||||
|             color: "#00000000" | ||||
|             anchors.left: asmTableView.right | ||||
|             anchors.right: parent.right | ||||
|             SplitView { | ||||
|                 orientation: Qt.Vertical | ||||
|                 anchors.fill: parent | ||||
| 
 | ||||
| 				TableView { | ||||
| 					property var memModel: ListModel { | ||||
| 						id: memModel | ||||
| 					} | ||||
| 					height: parent.height/2 | ||||
| 					width: parent.width | ||||
| 					TableViewColumn{ id:mnumColmn ; role: "num" ; title: "#" ; width: 50} | ||||
| 					TableViewColumn{ role: "value" ; title: "Memory" ; width: 750} | ||||
| 					model: memModel | ||||
| 				} | ||||
|                 Rectangle { | ||||
|                     color: "#00000000" | ||||
|                     height: 500 | ||||
|                     anchors.left: parent.left | ||||
|                     anchors.right: parent.right | ||||
| 
 | ||||
| 				SplitView { | ||||
| 					orientation: Qt.Horizontal | ||||
| 					TableView { | ||||
| 						property var debuggerLog: ListModel { | ||||
| 							id: debuggerLog | ||||
| 						} | ||||
| 						TableViewColumn{ role: "value"; title: "Debug messages" } | ||||
| 						model: debuggerLog | ||||
| 					} | ||||
| 					TableView { | ||||
| 						property var stackModel: ListModel { | ||||
| 							id: stackModel | ||||
| 						} | ||||
| 						height: parent.height/2 | ||||
| 						width: parent.width | ||||
| 						TableViewColumn{ role: "value" ; title: "Stack" ; width: 200 } | ||||
| 						model: stackModel | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	statusBar: StatusBar { | ||||
| 		RowLayout { | ||||
| 			anchors.fill: parent | ||||
| 			Button { | ||||
| 				property var enabled: true | ||||
| 				id: debugNextButton | ||||
| 				onClicked: { | ||||
| 					//db.next() | ||||
| 				} | ||||
| 				text: "Next" | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|                     TextArea { | ||||
|                         id: codeEditor | ||||
|                         anchors.top: parent.top | ||||
|                         anchors.bottom: parent.bottom | ||||
|                         anchors.left: parent.left | ||||
|                         anchors.right: settings.left | ||||
|                     } | ||||
| 
 | ||||
| 	function setAsm(asm) { | ||||
| 		asmModel.append({asm: asm}) | ||||
| 	} | ||||
|                     Column { | ||||
|                         id: settings | ||||
|                         spacing: 5 | ||||
|                         width: 300 | ||||
|                         height: parent.height | ||||
|                         anchors.right: parent.right | ||||
|                         anchors.top: parent.top | ||||
|                         anchors.bottom: parent.bottom | ||||
| 
 | ||||
| 	function setInstruction(num) { | ||||
| 		asmTableView.selection.clear() | ||||
| 		asmTableView.selection.select(num-1) | ||||
| 	} | ||||
|                         Label { | ||||
|                             text: "Data" | ||||
|                         } | ||||
|                         TextArea { | ||||
|                             anchors.left: parent.left | ||||
|                             anchors.right: parent.right | ||||
|                             height: 150 | ||||
|                         } | ||||
| 
 | ||||
| 	function clearAsm() { | ||||
| 		asmModel.clear() | ||||
| 	} | ||||
|                         Label { | ||||
|                             text: "Amount" | ||||
|                         } | ||||
|                         TextField { | ||||
|                             id: txValue | ||||
|                             width: 200 | ||||
|                             placeholderText: "Amount" | ||||
|                             validator: RegExpValidator { regExp: /\d*/ } | ||||
|                         } | ||||
|                         Label { | ||||
|                             text: "Amount of gas" | ||||
|                         } | ||||
|                         TextField { | ||||
|                             id: txGas | ||||
|                             width: 200 | ||||
|                             validator: RegExpValidator { regExp: /\d*/ } | ||||
|                             text: "10000" | ||||
|                             placeholderText: "Gas" | ||||
|                         } | ||||
|                         Label { | ||||
|                             text: "Gas price" | ||||
|                         } | ||||
|                         TextField { | ||||
|                             id: txGasPrice | ||||
|                             width: 200 | ||||
|                             placeholderText: "Gas price" | ||||
|                             text: "1000000000000" | ||||
|                             validator: RegExpValidator { regExp: /\d*/ } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
| 	function setMem(mem) { | ||||
| 		memModel.append({num: mem.num, value: mem.value}) | ||||
| 	} | ||||
| 	function clearMem(){ | ||||
| 		memModel.clear() | ||||
| 	} | ||||
|                 SplitView { | ||||
|                     orientation: Qt.Vertical | ||||
|                     id: inspectorPane | ||||
|                     height: 500 | ||||
| 
 | ||||
| 	function setStack(stack) { | ||||
| 		stackModel.append({value: stack}) | ||||
| 	} | ||||
| 	function addDebugMessage(message){ | ||||
| 		debuggerLog.append({value: message}) | ||||
| 	} | ||||
|                     SplitView { | ||||
|                         orientation: Qt.Horizontal | ||||
|                         height: 300 | ||||
| 
 | ||||
| 	function clearStack() { | ||||
| 		stackModel.clear() | ||||
| 	} | ||||
|                         TableView { | ||||
|                             id: stackTableView | ||||
|                             property var stackModel: ListModel { | ||||
|                                 id: stackModel | ||||
|                             } | ||||
|                             height: parent.height | ||||
|                             width: 300 | ||||
|                             TableViewColumn{ role: "value" ; title: "Stack" ; width: 200 } | ||||
|                             model: stackModel | ||||
|                         } | ||||
| 
 | ||||
|                         TableView { | ||||
|                             id: memoryTableView | ||||
|                             property var memModel: ListModel { | ||||
|                                 id: memModel | ||||
|                             } | ||||
|                             height: parent.height | ||||
|                             width: parent.width - stackTableView.width | ||||
|                             TableViewColumn{ id:mnumColmn ; role: "num" ; title: "#" ; width: 50} | ||||
|                             TableViewColumn{ role: "value" ; title: "Memory" ; width: 750} | ||||
|                             model: memModel | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     SplitView { | ||||
|                         height: 300 | ||||
|                         TableView { | ||||
|                             id: storageTableView | ||||
|                             property var memModel: ListModel { | ||||
|                                 id: storageModel | ||||
|                             } | ||||
|                             height: parent.height | ||||
|                             width: parent.width - stackTableView.width | ||||
|                             TableViewColumn{ id: key ; role: "key" ; title: "#" ; width: storageTableView.width / 2} | ||||
|                             TableViewColumn{ role: "value" ; title: "value" ; width:  storageTableView.width / 2} | ||||
|                             model: storageModel | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     statusBar: StatusBar { | ||||
|         RowLayout { | ||||
|             spacing: 5 | ||||
|             anchors.fill: parent | ||||
| 
 | ||||
|             Button { | ||||
|                 property var enabled: true | ||||
|                 id: debugStart | ||||
|                 onClicked: { | ||||
|                     dbg.debug(txValue.text, txGas.text, txGasPrice.text, codeEditor.text) | ||||
|                 } | ||||
|                 text: "Debug" | ||||
|             } | ||||
| 
 | ||||
|             Button { | ||||
|                 property var enabled: true | ||||
|                 id: debugNextButton | ||||
|                 onClicked: { | ||||
|                     dbg.next() | ||||
|                 } | ||||
|                 text: "Next" | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function setAsm(asm) { | ||||
|         console.log("set asm", asm) | ||||
|         asmModel.append({asm: asm}) | ||||
|     } | ||||
| 
 | ||||
|     function setInstruction(num) { | ||||
|         asmTableView.selection.clear() | ||||
|         asmTableView.selection.select(num-1) | ||||
|     } | ||||
| 
 | ||||
|     function clearAsm() { | ||||
|         asmModel.clear() | ||||
|     } | ||||
| 
 | ||||
|     function setMem(mem) { | ||||
|         memModel.append({num: mem.num, value: mem.value}) | ||||
|     } | ||||
|     function clearMem(){ | ||||
|         memModel.clear() | ||||
|     } | ||||
| 
 | ||||
|     function setStack(stack) { | ||||
|         stackModel.append({value: stack}) | ||||
|     } | ||||
|     function addDebugMessage(message){ | ||||
|         debuggerLog.append({value: message}) | ||||
|     } | ||||
| 
 | ||||
|     function clearStack() { | ||||
|         stackModel.clear() | ||||
|     } | ||||
| 
 | ||||
|     function clearStorage() { | ||||
|         storageModel.clear() | ||||
|     } | ||||
| 
 | ||||
|     function setStorage(storage) { | ||||
|         storageModel.append({key: storage.key, value: storage.value}) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -30,13 +30,16 @@ func NewDebuggerWindow(lib *UiLib) *DebuggerWindow { | ||||
| } | ||||
| 
 | ||||
| func (self *DebuggerWindow) Show() { | ||||
| 	context := self.engine.Context() | ||||
| 	context.SetVar("dbg", self) | ||||
| 
 | ||||
| 	go func() { | ||||
| 		self.win.Show() | ||||
| 		self.win.Wait() | ||||
| 	}() | ||||
| } | ||||
| 
 | ||||
| func (self *DebuggerWindow) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string) { | ||||
| func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, data string) { | ||||
| 	state := self.lib.eth.BlockChain().CurrentBlock.State() | ||||
| 
 | ||||
| 	script, err := ethutil.Compile(data) | ||||
| @ -50,14 +53,14 @@ func (self *DebuggerWindow) DebugTx(recipient, valueStr, gasStr, gasPriceStr, da | ||||
| 	self.lib.win.Root().Call("clearAsm") | ||||
| 
 | ||||
| 	for _, str := range dis { | ||||
| 		self.lib.win.Root().Call("setAsm", str) | ||||
| 		self.win.Root().Call("setAsm", str) | ||||
| 	} | ||||
| 	// Contract addr as test address
 | ||||
| 	keyPair := ethutil.GetKeyRing().Get(0) | ||||
| 	callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), ethutil.Big(gasStr), ethutil.Big(gasPriceStr), script) | ||||
| 	callerTx.Sign(keyPair.PrivateKey) | ||||
| 
 | ||||
| 	account := self.lib.eth.StateManager().TransState().GetStateObject(keyPair.Address()) | ||||
| 	account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address()) | ||||
| 	contract := ethchain.MakeContract(callerTx, state) | ||||
| 	callerClosure := ethchain.NewClosure(account, contract, contract.Init(), state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr)) | ||||
| 
 | ||||
| @ -84,3 +87,49 @@ func (self *DebuggerWindow) DebugTx(recipient, valueStr, gasStr, gasPriceStr, da | ||||
| func (self *DebuggerWindow) Next() { | ||||
| 	self.Db.Next() | ||||
| } | ||||
| 
 | ||||
| type Debugger struct { | ||||
| 	win  *qml.Window | ||||
| 	N    chan bool | ||||
| 	done bool | ||||
| } | ||||
| 
 | ||||
| type storeVal struct { | ||||
| 	Key, Value string | ||||
| } | ||||
| 
 | ||||
| func (d *Debugger) halting(pc int, op ethchain.OpCode, mem *ethchain.Memory, stack *ethchain.Stack, stateObject *ethchain.StateObject) { | ||||
| 	d.win.Root().Call("setInstruction", pc) | ||||
| 	d.win.Root().Call("clearMem") | ||||
| 	d.win.Root().Call("clearStack") | ||||
| 	d.win.Root().Call("clearStorage") | ||||
| 
 | ||||
| 	addr := 0 | ||||
| 	for i := 0; i+32 <= mem.Len(); i += 32 { | ||||
| 		d.win.Root().Call("setMem", memAddr{fmt.Sprintf("%03d", addr), fmt.Sprintf("% x", mem.Data()[i:i+32])}) | ||||
| 		addr++ | ||||
| 	} | ||||
| 
 | ||||
| 	for _, val := range stack.Data() { | ||||
| 		d.win.Root().Call("setStack", val.String()) | ||||
| 	} | ||||
| 
 | ||||
| 	stateObject.State().EachStorage(func(key string, node *ethutil.Value) { | ||||
| 		d.win.Root().Call("setStorage", storeVal{fmt.Sprintf("% x", key), fmt.Sprintf("% x", node.Str())}) | ||||
| 	}) | ||||
| 
 | ||||
| out: | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-d.N: | ||||
| 			break out | ||||
| 		default: | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (d *Debugger) Next() { | ||||
| 	if !d.done { | ||||
| 		d.N <- true | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -2,7 +2,6 @@ package ethui | ||||
| 
 | ||||
| import ( | ||||
| 	"bitbucket.org/kardianos/osext" | ||||
| 	"fmt" | ||||
| 	"github.com/ethereum/eth-go" | ||||
| 	"github.com/ethereum/eth-go/ethchain" | ||||
| 	"github.com/ethereum/eth-go/ethutil" | ||||
| @ -171,40 +170,3 @@ func (ui *UiLib) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string) | ||||
| func (ui *UiLib) Next() { | ||||
| 	ui.Db.Next() | ||||
| } | ||||
| 
 | ||||
| type Debugger struct { | ||||
| 	win  *qml.Window | ||||
| 	N    chan bool | ||||
| 	done bool | ||||
| } | ||||
| 
 | ||||
| func (d *Debugger) halting(pc int, op ethchain.OpCode, mem *ethchain.Memory, stack *ethchain.Stack) { | ||||
| 	d.win.Root().Call("setInstruction", pc) | ||||
| 	d.win.Root().Call("clearMem") | ||||
| 	d.win.Root().Call("clearStack") | ||||
| 
 | ||||
| 	addr := 0 | ||||
| 	for i := 0; i+32 <= mem.Len(); i += 32 { | ||||
| 		d.win.Root().Call("setMem", memAddr{fmt.Sprintf("%03d", addr), fmt.Sprintf("% x", mem.Data()[i:i+32])}) | ||||
| 		addr++ | ||||
| 	} | ||||
| 
 | ||||
| 	for _, val := range stack.Data() { | ||||
| 		d.win.Root().Call("setStack", val.String()) | ||||
| 	} | ||||
| 
 | ||||
| out: | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-d.N: | ||||
| 			break out | ||||
| 		default: | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (d *Debugger) Next() { | ||||
| 	if !d.done { | ||||
| 		d.N <- true | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user