tgo
tgo copied to clipboard
panic: runtime error: hash of unhashable type tracee.arrayValue
my go version is 1.12 os is mac 10.13.6
Thank you for opening the issue. Can you share the stack trace? The code snippet to reproduce the issue is best.
for i, tt := range tests {
// Create the account pool and generate the initial set of signers
accounts := newTesterAccountPool()
signers := make([]common.Address, len(tt.signers))
for j, signer := range tt.signers {
signers[j] = accounts.address(signer)
}
//对signer进行排序
for j := 0; j < len(signers); j++ {
for k := j + 1; k < len(signers); k++ {
if bytes.Compare(signers[j][:], signers[k][:]) > 0 {
signers[j], signers[k] = signers[k], signers[j]
}
}
}
// Create the genesis block with the initial set of signers
genesis := &core.Genesis{
ExtraData: make([]byte, extraVanity+common.AddressLength*len(signers)+extraSeal),
}
//放到Extra中
for j, signer := range signers {
copy(genesis.ExtraData[extraVanity+j*common.AddressLength:], signer[:])
}
// Create a pristine blockchain with the genesis injected
db := ethdb.NewMemDatabase()
genesis.Commit(db)
// Assemble a chain of headers from the cast votes
config := *params.TestChainConfig
config.Clique = ¶ms.CliqueConfig{
Period: 1,
Epoch: tt.epoch,
}
engine := New(config.Clique, db)
engine.fakeDiff = true
blocks, _ := core.GenerateChain(&config, genesis.ToBlock(db), engine, db, len(tt.votes), func(j int, gen *core.BlockGen) {
// Cast the vote contained in this block
gen.SetCoinbase(accounts.address(tt.votes[j].voted))
if tt.votes[j].auth {
var nonce types.BlockNonce
copy(nonce[:], nonceAuthVote)
gen.SetNonce(nonce)
}
})
// Iterate through the blocks and seal them individually
for j, block := range blocks {
// Geth the header and prepare it for signing
header := block.Header()
if j > 0 {
header.ParentHash = blocks[j-1].Hash()
}
header.Extra = make([]byte, extraVanity+extraSeal)
if auths := tt.votes[j].checkpoint; auths != nil {
header.Extra = make([]byte, extraVanity+len(auths)*common.AddressLength+extraSeal)
accounts.checkpoint(header, auths)
}
header.Difficulty = diffInTurn // Ignored, we just need a valid number
// Generate the signature, embed it into the header and the block
accounts.sign(header, tt.votes[j].signer)
blocks[j] = block.WithSeal(header)
}
// Split the blocks up into individual import batches (cornercase testing)
batches := [][]*types.Block{nil}
for j, block := range blocks {
if tt.votes[j].newbatch {
batches = append(batches, nil)
}
batches[len(batches)-1] = append(batches[len(batches)-1], block)
}
tracer.SetTraceLevel(4)
//tracer.SetParseLevel(5)
tracer.SetVerboseOption(true)
tracer.Start()
// Pass all the headers through clique and ensure tallying succeeds
chain, err := core.NewBlockChain(db, nil, &config, engine, vm.Config{}, nil)
if err != nil {
t.Errorf("test %d: failed to create test chain: %v", i, err)
continue
}
failed := false
for j := 0; j < len(batches)-1; j++ {
if k, err := chain.InsertChain(batches[j]); err != nil {
t.Errorf("test %d: failed to import batch %d, block %d: %v", i, j, k, err)
failed = true
break
}
}
if failed {
continue
}
if _, err = chain.InsertChain(batches[len(batches)-1]); err != tt.failure {
t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure)
return
}
if tt.failure != nil {
continue
}
// No failure was produced or requested, generate the final voting snapshot
head := blocks[len(blocks)-1]
snap, err := engine.snapshot(chain, head.NumberU64(), head.Hash(), nil)
if err != nil {
t.Errorf("test %d: failed to retrieve voting snapshot: %v", i, err)
continue
}
// Verify the final list of signers against the expected ones
signers = make([]common.Address, len(tt.results))
for j, signer := range tt.results {
signers[j] = accounts.address(signer)
}
//插入排序
for j := 0; j < len(signers); j++ {
for k := j + 1; k < len(signers); k++ {
if bytes.Compare(signers[j][:], signers[k][:]) > 0 {
signers[j], signers[k] = signers[k], signers[j]
}
}
}
result := snap.signers()
if len(result) != len(signers) {
t.Errorf("test %d: signers mismatch: have %x, want %x", i, result, signers)
continue
}
for j := 0; j < len(result); j++ {
if !bytes.Equal(result[j][:], signers[j][:]) {
t.Errorf("test %d, signer %d: signer mismatch: have %x, want %x", i, j, result[j], signers[j])
}
}
tracer.Stop()
break
}
// Tests that Clique signer voting is evaluated correctly for various simple and
// complex scenarios, as well as that a few special corner cases fail correctly.
func TestClique(t *testing.T) {
this function of https://github.com/ethereum/go-ethereum in this file : consensus/clique/snapshot_test.go
stack: panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x135f586]
goroutine 11 [running]: github.com/nkbai/tgo/tracee.(*moduleData).retrieveUint64(0x0, 0x14d8bc0, 0xc00012a180, 0x144c2b0, 0x5, 0x46bb2e0) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/moduledata.go:141 +0x26 github.com/nkbai/tgo/tracee.(*moduleData).types(...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/moduledata.go:84 github.com/nkbai/tgo/tracee.(*Process).mapRuntimeType(0xc00015e400, 0x202020202020202, 0xc0001b6240, 0xc001428200, 0xc0001b6248, 0xc001428180) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/process.go:116 +0xf8 github.com/nkbai/tgo/tracee.valueParser.parseEmptyInterfaceValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0xc0014260c0, 0xc0006c6420, 0x10, 0x10, 0x0, 0x0, 0x0, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:484 +0x196 github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0500, 0xc0014260c0, 0xc0006c6420, 0x10, 0x10, 0x0, 0x17daa20, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:376 +0xc5e github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0540, 0xc001422cf0, 0xc0006c6420, 0x10, 0x10, 0x0, 0xc000376400, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:396 +0x12e6 github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0540, 0xc001422c90, 0xc0006c6420, 0x10, 0x10, 0x0, 0xc000376630, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:396 +0x12e6 github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0540, 0xc001422c30, 0xc0006c6420, 0x10, 0x10, 0x0, 0x203000, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:396 +0x12e6 github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0480, 0xc0014feb10, 0xc0013baf00, 0x8, 0x20, 0x0, 0xc0019f6450, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:359 +0x767 github.com/nkbai/tgo/tracee.valueParser.parseStructValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0xc001680480, 0xc0013baf00, 0x18, 0x20, 0x1, 0x0, 0x58, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:513 +0x17b github.com/nkbai/tgo/tracee.valueParser.parseSliceValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0xc001680480, 0xc0013baf00, 0x18, 0x20, 0x0, 0xc000376da8, 0x100d2c9, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:415 +0x9f github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0500, 0xc001680480, 0xc0013baf00, 0x18, 0x20, 0x0, 0xc00068ec88, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:372 +0xe23 github.com/nkbai/tgo/tracee.valueParser.parseStructValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0xc001680420, 0xc0013baf00, 0x20, 0x20, 0x1, 0xa, 0xa, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:513 +0x17b github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0500, 0xc001680420, 0xc0013baf00, 0x20, 0x20, 0x1, 0xc0003773d0, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:378 +0xb8d github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0540, 0xc0019f6150, 0xc0013baf00, 0x20, 0x20, 0x1, 0xc0003776b0, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:396 +0x12e6 github.com/nkbai/tgo/tracee.valueParser.parseValue(0x14d8bc0, 0xc00012a180, 0xc001450000, 0x14e0480, 0xc0019f60f0, 0xc0006c63e8, 0x8, 0x8, 0x1, 0xc0006fecb8, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/value.go:359 +0x767 github.com/nkbai/tgo/tracee.(*Process).currentArgs.func1(0x1, 0x1042c92, 0xc0006c63e0) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/process.go:674 +0x230 github.com/nkbai/tgo/tracee.Argument.ParseValue(0x177ce2c, 0x1, 0x14e0480, 0xc0019f60f0, 0xc0000c0550, 0x1, 0x1, 0xeabff1b3f1ea634) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracee/process.go:929 +0x3a github.com/nkbai/tgo/tracer.(*Controller).printFunctionInput(0xc0001266c0, 0x2a, 0xc0017d9f40, 0x3, 0xc0001ecb00, 0x40f8d30) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracer/controller.go:572 +0xf4 github.com/nkbai/tgo/tracer.(*Controller).handleTrapAtFunctionCall(0xc0001266c0, 0x100753b, 0x41eddb0, 0x2a, 0x3500, 0x41eddb0, 0xc0001ecb00, 0x40f8d30, 0x0, 0xc00066f850, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracer/controller.go:437 +0x3f4 github.com/nkbai/tgo/tracer.(*Controller).handleTrapBeforeFunctionCall(0xc0001266c0, 0x100753b, 0x2a, 0x3500, 0x41eddb0, 0xc0001ecb00, 0x40f8d30, 0x0, 0xc00066f850, 0x0, ...) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracer/controller.go:394 +0x205 github.com/nkbai/tgo/tracer.(*Controller).handleTrapEventOfThread(0xc0001266c0, 0x100753b, 0x13b0020, 0xc001b11340) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracer/controller.go:269 +0x247 github.com/nkbai/tgo/tracer.(*Controller).handleTrapEvent(0xc0001266c0, 0xc00066f2e0, 0x1, 0x1, 0x0, 0x13b0020, 0xc001b11340, 0x0, 0x0) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracer/controller.go:230 +0x79 github.com/nkbai/tgo/tracer.(*Controller).MainLoop(0xc0001266c0, 0x0, 0x0) /Volumes/dev/godev/src/github.com/nkbai/tgo/tracer/controller.go:171 +0x1f4 github.com/nkbai/tgo/service.(*Tracer).Attach.func1(0xc0000aa0e0) /Volumes/dev/godev/src/github.com/nkbai/tgo/service/service.go:65 +0x32 created by github.com/nkbai/tgo/service.(*Tracer).Attach /Volumes/dev/godev/src/github.com/nkbai/tgo/service/service.go:64 +0x366
Thank you. I will take a look.
Sorry for being late. I tried to reproduce the bug, but it works as expected.
$ go version
go version go1.12.1 darwin/amd64
$ go test -v -run='TestClique' .
=== RUN TestClique
Start tracing of go routine #34
// Too long. Skipped.
End tracing of go routine #34
--- PASS: TestClique (34.16s)
PASS
ok github.com/ethereum/go-ethereum/consensus/clique 34.199s
Mac version is 10.14.4.
It's like the argument to *Process.mapRuntimeType()
is strange (runtimeTypeAddr
is 0x202020202020202
). Maybe the dwarf.StructType
is not parsed correctly, but it's difficult to investigate further without reproducing the bug.