New debugger
This commit is contained in:
		
							parent
							
								
									4fd267a778
								
							
						
					
					
						commit
						d0b31e2030
					
				| @ -7,13 +7,12 @@ import QtQuick.Controls.Styles 1.1 | |||||||
| import Ethereum 1.0 | import Ethereum 1.0 | ||||||
| 
 | 
 | ||||||
| ApplicationWindow { | ApplicationWindow { | ||||||
| 	id: debugWindow |  | ||||||
|     visible: false |     visible: false | ||||||
|     title: "Debugger" |     title: "Debugger" | ||||||
| 	minimumWidth: 600 |     minimumWidth: 1280 | ||||||
| 	minimumHeight: 600 |     minimumHeight: 900 | ||||||
| 	width: 800 |     width: 1290 | ||||||
| 	height: 600 |     height: 900 | ||||||
| 
 | 
 | ||||||
|     SplitView { |     SplitView { | ||||||
|         anchors.fill: parent |         anchors.fill: parent | ||||||
| @ -28,40 +27,123 @@ ApplicationWindow { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Rectangle { |         Rectangle { | ||||||
|  |             color: "#00000000" | ||||||
|             anchors.left: asmTableView.right |             anchors.left: asmTableView.right | ||||||
|             anchors.right: parent.right |             anchors.right: parent.right | ||||||
|             SplitView { |             SplitView { | ||||||
|                 orientation: Qt.Vertical |                 orientation: Qt.Vertical | ||||||
|                 anchors.fill: parent |                 anchors.fill: parent | ||||||
| 
 | 
 | ||||||
|  |                 Rectangle { | ||||||
|  |                     color: "#00000000" | ||||||
|  |                     height: 500 | ||||||
|  |                     anchors.left: parent.left | ||||||
|  |                     anchors.right: parent.right | ||||||
|  | 
 | ||||||
|  |                     TextArea { | ||||||
|  |                         id: codeEditor | ||||||
|  |                         anchors.top: parent.top | ||||||
|  |                         anchors.bottom: parent.bottom | ||||||
|  |                         anchors.left: parent.left | ||||||
|  |                         anchors.right: settings.left | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     Column { | ||||||
|  |                         id: settings | ||||||
|  |                         spacing: 5 | ||||||
|  |                         width: 300 | ||||||
|  |                         height: parent.height | ||||||
|  |                         anchors.right: parent.right | ||||||
|  |                         anchors.top: parent.top | ||||||
|  |                         anchors.bottom: parent.bottom | ||||||
|  | 
 | ||||||
|  |                         Label { | ||||||
|  |                             text: "Data" | ||||||
|  |                         } | ||||||
|  |                         TextArea { | ||||||
|  |                             anchors.left: parent.left | ||||||
|  |                             anchors.right: parent.right | ||||||
|  |                             height: 150 | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         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*/ } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 SplitView { | ||||||
|  |                     orientation: Qt.Vertical | ||||||
|  |                     id: inspectorPane | ||||||
|  |                     height: 500 | ||||||
|  | 
 | ||||||
|  |                     SplitView { | ||||||
|  |                         orientation: Qt.Horizontal | ||||||
|  |                         height: 300 | ||||||
|  | 
 | ||||||
|                         TableView { |                         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 { |                             property var memModel: ListModel { | ||||||
|                                 id: memModel |                                 id: memModel | ||||||
|                             } |                             } | ||||||
| 					height: parent.height/2 |                             height: parent.height | ||||||
| 					width: parent.width |                             width: parent.width - stackTableView.width | ||||||
|                             TableViewColumn{ id:mnumColmn ; role: "num" ; title: "#" ; width: 50} |                             TableViewColumn{ id:mnumColmn ; role: "num" ; title: "#" ; width: 50} | ||||||
|                             TableViewColumn{ role: "value" ; title: "Memory" ; width: 750} |                             TableViewColumn{ role: "value" ; title: "Memory" ; width: 750} | ||||||
|                             model: memModel |                             model: memModel | ||||||
|                         } |                         } | ||||||
|  |                     } | ||||||
| 
 | 
 | ||||||
|                     SplitView { |                     SplitView { | ||||||
| 					orientation: Qt.Horizontal |                         height: 300 | ||||||
|                         TableView { |                         TableView { | ||||||
| 						property var debuggerLog: ListModel { |                             id: storageTableView | ||||||
| 							id: debuggerLog |                             property var memModel: ListModel { | ||||||
|  |                                 id: storageModel | ||||||
|                             } |                             } | ||||||
| 						TableViewColumn{ role: "value"; title: "Debug messages" } |                             height: parent.height | ||||||
| 						model: debuggerLog |                             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 | ||||||
|                         } |                         } | ||||||
| 					TableView { |  | ||||||
| 						property var stackModel: ListModel { |  | ||||||
| 							id: stackModel |  | ||||||
| 						} |  | ||||||
| 						height: parent.height/2 |  | ||||||
| 						width: parent.width |  | ||||||
| 						TableViewColumn{ role: "value" ; title: "Stack" ; width: 200 } |  | ||||||
| 						model: stackModel |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @ -69,12 +151,23 @@ ApplicationWindow { | |||||||
|     } |     } | ||||||
|     statusBar: StatusBar { |     statusBar: StatusBar { | ||||||
|         RowLayout { |         RowLayout { | ||||||
|  |             spacing: 5 | ||||||
|             anchors.fill: parent |             anchors.fill: parent | ||||||
|  | 
 | ||||||
|  |             Button { | ||||||
|  |                 property var enabled: true | ||||||
|  |                 id: debugStart | ||||||
|  |                 onClicked: { | ||||||
|  |                     dbg.debug(txValue.text, txGas.text, txGasPrice.text, codeEditor.text) | ||||||
|  |                 } | ||||||
|  |                 text: "Debug" | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             Button { |             Button { | ||||||
|                 property var enabled: true |                 property var enabled: true | ||||||
|                 id: debugNextButton |                 id: debugNextButton | ||||||
|                 onClicked: { |                 onClicked: { | ||||||
| 					//db.next() |                     dbg.next() | ||||||
|                 } |                 } | ||||||
|                 text: "Next" |                 text: "Next" | ||||||
|             } |             } | ||||||
| @ -82,6 +175,7 @@ ApplicationWindow { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     function setAsm(asm) { |     function setAsm(asm) { | ||||||
|  |         console.log("set asm", asm) | ||||||
|         asmModel.append({asm: asm}) |         asmModel.append({asm: asm}) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -111,4 +205,12 @@ ApplicationWindow { | |||||||
|     function clearStack() { |     function clearStack() { | ||||||
|         stackModel.clear() |         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() { | func (self *DebuggerWindow) Show() { | ||||||
|  | 	context := self.engine.Context() | ||||||
|  | 	context.SetVar("dbg", self) | ||||||
|  | 
 | ||||||
| 	go func() { | 	go func() { | ||||||
| 		self.win.Show() | 		self.win.Show() | ||||||
| 		self.win.Wait() | 		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() | 	state := self.lib.eth.BlockChain().CurrentBlock.State() | ||||||
| 
 | 
 | ||||||
| 	script, err := ethutil.Compile(data) | 	script, err := ethutil.Compile(data) | ||||||
| @ -50,14 +53,14 @@ func (self *DebuggerWindow) DebugTx(recipient, valueStr, gasStr, gasPriceStr, da | |||||||
| 	self.lib.win.Root().Call("clearAsm") | 	self.lib.win.Root().Call("clearAsm") | ||||||
| 
 | 
 | ||||||
| 	for _, str := range dis { | 	for _, str := range dis { | ||||||
| 		self.lib.win.Root().Call("setAsm", str) | 		self.win.Root().Call("setAsm", str) | ||||||
| 	} | 	} | ||||||
| 	// Contract addr as test address
 | 	// Contract addr as test address
 | ||||||
| 	keyPair := ethutil.GetKeyRing().Get(0) | 	keyPair := ethutil.GetKeyRing().Get(0) | ||||||
| 	callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), ethutil.Big(gasStr), ethutil.Big(gasPriceStr), script) | 	callerTx := ethchain.NewContractCreationTx(ethutil.Big(valueStr), ethutil.Big(gasStr), ethutil.Big(gasPriceStr), script) | ||||||
| 	callerTx.Sign(keyPair.PrivateKey) | 	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) | 	contract := ethchain.MakeContract(callerTx, state) | ||||||
| 	callerClosure := ethchain.NewClosure(account, contract, contract.Init(), state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr)) | 	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() { | func (self *DebuggerWindow) Next() { | ||||||
| 	self.Db.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 ( | import ( | ||||||
| 	"bitbucket.org/kardianos/osext" | 	"bitbucket.org/kardianos/osext" | ||||||
| 	"fmt" |  | ||||||
| 	"github.com/ethereum/eth-go" | 	"github.com/ethereum/eth-go" | ||||||
| 	"github.com/ethereum/eth-go/ethchain" | 	"github.com/ethereum/eth-go/ethchain" | ||||||
| 	"github.com/ethereum/eth-go/ethutil" | 	"github.com/ethereum/eth-go/ethutil" | ||||||
| @ -171,40 +170,3 @@ func (ui *UiLib) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string) | |||||||
| func (ui *UiLib) Next() { | func (ui *UiLib) Next() { | ||||||
| 	ui.Db.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