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