Commit b7c4d78e authored by hezhengjun's avatar hezhengjun Committed by vipwzw

correct data race of evm debug

parent ac1c8feb
...@@ -282,8 +282,8 @@ useBalance=false ...@@ -282,8 +282,8 @@ useBalance=false
#免交易费模式联盟链允许的最大gas,该配置只对不收取交易费部署方式有效,其他部署方式下该配置不会产生作用 #免交易费模式联盟链允许的最大gas,该配置只对不收取交易费部署方式有效,其他部署方式下该配置不会产生作用
#当前最大为200万 #当前最大为200万
evmGasLimit=2000000 evmGasLimit=2000000
#evm内部调试输出,指令级的,默认关闭 #evm内部调试输出,指令级的,默认关闭,0:关闭;1:打开
evmDebugEnable=false evmDebugEnable=0
[metrics] [metrics]
#是否使能发送metrics数据的发送 #是否使能发送metrics数据的发送
......
...@@ -24,10 +24,9 @@ var ( ...@@ -24,10 +24,9 @@ var (
evmDebugInited = false evmDebugInited = false
// EvmAddress 本合约地址 // EvmAddress 本合约地址
EvmAddress = "" EvmAddress = ""
driverName = evmtypes.ExecutorName
) )
var driverName = evmtypes.ExecutorName
// Init 初始化本合约对象 // Init 初始化本合约对象
func Init(name string, cfg *types.Chain33Config, sub []byte) { func Init(name string, cfg *types.Chain33Config, sub []byte) {
driverName = name driverName = name
......
...@@ -9,6 +9,7 @@ import ( ...@@ -9,6 +9,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
"sync/atomic"
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
...@@ -30,6 +31,13 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt, ...@@ -30,6 +31,13 @@ func (evm *EVMExecutor) Exec(tx *types.Transaction, index int) (*types.Receipt,
return nil, err return nil, err
} }
cfg := evm.GetAPI().GetConfig()
if !evmDebugInited {
conf := types.ConfSub(cfg, evmtypes.ExecutorName)
atomic.StoreInt32(&evm.vmCfg.Debug, int32(conf.GInt("evmDebugEnable")))
evmDebugInited = true
}
return evm.innerExec(msg, tx.Hash(), index, msg.GasLimit(), false) return evm.innerExec(msg, tx.Hash(), index, msg.GasLimit(), false)
} }
...@@ -39,11 +47,6 @@ func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int, ...@@ -39,11 +47,6 @@ func (evm *EVMExecutor) innerExec(msg *common.Message, txHash []byte, index int,
// 获取当前区块的上下文信息构造EVM上下文 // 获取当前区块的上下文信息构造EVM上下文
context := evm.NewEVMContext(msg, txHash) context := evm.NewEVMContext(msg, txHash)
cfg := evm.GetAPI().GetConfig() cfg := evm.GetAPI().GetConfig()
if !evmDebugInited {
conf := types.ConfSub(cfg, evmtypes.ExecutorName)
evm.vmCfg.Debug = conf.IsEnable("evmDebugEnable")
evmDebugInited = true
}
// 创建EVM运行时对象 // 创建EVM运行时对象
env := runtime.NewEVM(context, evm.mStateDB, *evm.vmCfg, cfg) env := runtime.NewEVM(context, evm.mStateDB, *evm.vmCfg, cfg)
isCreate := strings.Compare(msg.To().String(), EvmAddress) == 0 && len(msg.Data()) > 0 isCreate := strings.Compare(msg.To().String(), EvmAddress) == 0 && len(msg.Data()) > 0
......
...@@ -10,6 +10,9 @@ import ( ...@@ -10,6 +10,9 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"strings" "strings"
"sync/atomic"
"github.com/33cn/plugin/plugin/dapp/evm/executor/vm/runtime"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
...@@ -112,15 +115,15 @@ func getCallReceipt(logs []*types.ReceiptLog) *evmtypes.ReceiptEVMContract { ...@@ -112,15 +115,15 @@ func getCallReceipt(logs []*types.ReceiptLog) *evmtypes.ReceiptEVMContract {
return nil return nil
} }
// Query_EvmDebug 此方法用来估算合约消耗的Gas,不能修改原有执行器的状态数据 // Query_EvmDebug 此方法用来控制evm调试打印开关
func (evm *EVMExecutor) Query_EvmDebug(in *evmtypes.EvmDebugReq) (types.Message, error) { func (evm *EVMExecutor) Query_EvmDebug(in *evmtypes.EvmDebugReq) (types.Message, error) {
evm.CheckInit() evm.CheckInit()
optype := in.Optype optype := in.Optype
if optype < 0 { if optype < 0 {
evm.vmCfg.Debug = false atomic.StoreInt32(&evm.vmCfg.Debug, runtime.EVMDebugOff)
} else if optype > 0 { } else if optype > 0 {
evm.vmCfg.Debug = true atomic.StoreInt32(&evm.vmCfg.Debug, runtime.EVMDebugOn)
} }
ret := &evmtypes.EvmDebugResp{DebugStatus: fmt.Sprintf("%v", evm.vmCfg.Debug)} ret := &evmtypes.EvmDebugResp{DebugStatus: fmt.Sprintf("%v", evm.vmCfg.Debug)}
......
...@@ -189,7 +189,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas ...@@ -189,7 +189,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// 只有一种情况会走到这里来,就是合约账户向外部账户转账的情况 // 只有一种情况会走到这里来,就是合约账户向外部账户转账的情况
if len(input) > 0 || value == 0 { if len(input) > 0 || value == 0 {
// 其它情况要求地址必须存在,所以需要报错 // 其它情况要求地址必须存在,所以需要报错
if evm.VMConfig.Debug && evm.depth == 0 { if EVMDebugOn == evm.VMConfig.Debug && evm.depth == 0 {
evm.VMConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) evm.VMConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
evm.VMConfig.Tracer.CaptureEnd(ret, 0, 0, nil) evm.VMConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
} }
...@@ -238,7 +238,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas ...@@ -238,7 +238,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
start := types.Now() start := types.Now()
// 调试模式下启用跟踪 // 调试模式下启用跟踪
if evm.VMConfig.Debug && evm.depth == 0 { if EVMDebugOn == evm.VMConfig.Debug && evm.depth == 0 {
evm.VMConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value) evm.VMConfig.Tracer.CaptureStart(caller.Address(), addr, false, input, gas, value)
defer func() { defer func() {
...@@ -445,7 +445,7 @@ func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []b ...@@ -445,7 +445,7 @@ func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []b
snapshot = evm.StateDB.Snapshot() snapshot = evm.StateDB.Snapshot()
evm.StateDB.CreateAccount(contractAddr.String(), contract.CallerAddress.String(), execName, alias) evm.StateDB.CreateAccount(contractAddr.String(), contract.CallerAddress.String(), execName, alias)
if evm.VMConfig.Debug && evm.depth == 0 { if EVMDebugOn == evm.VMConfig.Debug && evm.depth == 0 {
evm.VMConfig.Tracer.CaptureStart(caller.Address(), contractAddr, true, code, gas, 0) evm.VMConfig.Tracer.CaptureStart(caller.Address(), contractAddr, true, code, gas, 0)
} }
start := types.Now() start := types.Now()
...@@ -482,7 +482,7 @@ func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []b ...@@ -482,7 +482,7 @@ func (evm *EVM) Create(caller ContractRef, contractAddr common.Address, code []b
err = model.ErrMaxCodeSizeExceeded err = model.ErrMaxCodeSizeExceeded
} }
if evm.VMConfig.Debug && evm.depth == 0 { if EVMDebugOn == evm.VMConfig.Debug && evm.depth == 0 {
evm.VMConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, types.Since(start), err) evm.VMConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, types.Since(start), err)
} }
......
...@@ -20,7 +20,7 @@ import ( ...@@ -20,7 +20,7 @@ import (
// Config 解释器的配置模型 // Config 解释器的配置模型
type Config struct { type Config struct {
// Debug 调试开关 // Debug 调试开关
Debug bool Debug int32
// Tracer 记录操作日志 // Tracer 记录操作日志
Tracer Tracer Tracer Tracer
// NoRecursion 不允许使用Call, CallCode, DelegateCall // NoRecursion 不允许使用Call, CallCode, DelegateCall
...@@ -41,6 +41,11 @@ type Interpreter struct { ...@@ -41,6 +41,11 @@ type Interpreter struct {
returnData []byte returnData []byte
} }
const (
EVMDebugOn = int32(1)
EVMDebugOff = int32(0)
)
// NewInterpreter 新创建一个解释器 // NewInterpreter 新创建一个解释器
func NewInterpreter(evm *EVM, cfg Config) *Interpreter { func NewInterpreter(evm *EVM, cfg Config) *Interpreter {
// 使用是否包含第一个STOP指令判断jump table是否完成初始化 // 使用是否包含第一个STOP指令判断jump table是否完成初始化
...@@ -126,7 +131,7 @@ func (in *Interpreter) Run(contract *Contract, input []byte, readOnly bool) (ret ...@@ -126,7 +131,7 @@ func (in *Interpreter) Run(contract *Contract, input []byte, readOnly bool) (ret
returnStack(stack) returnStack(stack)
}() }()
if in.cfg.Debug { if EVMDebugOn == in.cfg.Debug {
defer func() { defer func() {
if err != nil { if err != nil {
if !logged { if !logged {
...@@ -144,7 +149,7 @@ func (in *Interpreter) Run(contract *Contract, input []byte, readOnly bool) (ret ...@@ -144,7 +149,7 @@ func (in *Interpreter) Run(contract *Contract, input []byte, readOnly bool) (ret
if steps%1000 == 0 && atomic.LoadInt32(&in.evm.abort) != 0 { if steps%1000 == 0 && atomic.LoadInt32(&in.evm.abort) != 0 {
break break
} }
if in.cfg.Debug { if EVMDebugOn == in.cfg.Debug {
// 记录当前指令执行前的状态数据 // 记录当前指令执行前的状态数据
logged, pcCopy, gasCopy = false, pc, contract.Gas logged, pcCopy, gasCopy = false, pc, contract.Gas
} }
...@@ -210,7 +215,7 @@ func (in *Interpreter) Run(contract *Contract, input []byte, readOnly bool) (ret ...@@ -210,7 +215,7 @@ func (in *Interpreter) Run(contract *Contract, input []byte, readOnly bool) (ret
mem.Resize(memorySize) mem.Resize(memorySize)
} }
if in.cfg.Debug { if EVMDebugOn == in.cfg.Debug {
in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, in.returnData, contract, in.evm.depth, err) in.cfg.Tracer.CaptureState(in.evm, pc, op, gasCopy, cost, mem, stack, in.returnData, contract, in.evm.depth, err)
logged = true logged = true
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment