Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/gob: memory corruption decoding interface #3175

Closed
gopherbot opened this issue Mar 2, 2012 · 13 comments
Closed

encoding/gob: memory corruption decoding interface #3175

gopherbot opened this issue Mar 2, 2012 · 13 comments
Milestone

Comments

@gopherbot
Copy link

@gopherbot gopherbot commented Mar 2, 2012

by werner.hattingh:

What steps will reproduce the problem?
1. run my experiment_test.go unit test


What is the expected output?
For the unit test to pass

What do you see instead?
Few different result is seen on different runs
*********** RESULT 1 ***********
panic: runtime error: call of nil func value [recovered]
    panic: runtime error: call of nil func value [recovered]
    panic: runtime error: call of nil func value
[signal 0xb code=0x1 addr=0x0 pc=0x0]

goroutine 4 [running]:
encoding/gob.catchError(0xf8400a80b8, 0x7f47337ae100)
    /home/whattingh/go/src/pkg/encoding/gob/error.go:38 +0x9a
----- stack segment boundary -----
encoding/gob.catchError(0xf8400a80b8, 0x7f47337ae100)
    /home/whattingh/go/src/pkg/encoding/gob/error.go:38 +0x9a
----- stack segment boundary -----
encoding/gob.(*Decoder).decodeArrayHelper(0xf8400a8000, 0xf84009fd80, 0xf84016d1c0, 0x0,
0x10, ...)
    /home/whattingh/go/src/pkg/encoding/gob/decode.go:565 +0xb2
encoding/gob.(*Decoder).decodeSlice(0xf8400a8000, 0xf840074000, 0x4bf448, 0xf84009fd80,
0xf84016d1f0, ...)
    /home/whattingh/go/src/pkg/encoding/gob/decode.go:668 +0x160
encoding/gob._func_003(0xf8400ab2a0, 0xf84006bc10, 0xf84006bc18, 0xf8400ab2d0, 0x46c1de,
...)
    /home/whattingh/go/src/pkg/encoding/gob/decode.go:866 +0xf7
encoding/gob.(*Decoder).decodeStruct(0xf8400a8000, 0xf8400ad0a0, 0xf84009f300,
0xf84016d1e0, 0x100000000, ...)



*********** RESULT 2 ***********
panic: invalid memory address or nil pointer dereference
throw: panic during gc
[signal 0xb code=0x1 addr=0x0 pc=0x4086f7]

goroutine 3 [running]:
net.ResolveTCPAddr(0x53d104, 0x70637400000003, 0x548dfc, 0x322e313100000011,
0xf8400de7e0, ...)
    /home/whattingh/go/src/pkg/net/tcpsock.go:35 +0xcd
pkg/experiment.regReq(0xf8400dfe90, 0x100000001, 0x7f4eaac98eb8, 0x100000001, 0x8, ...)
    /home/whattingh/experiment/src/pkg/experiment/experiment_test.go:86 +0x9c
pkg/experiment.ClientDriver(0xbb8, 0x54909c, 0xc, 0xbb840080270)
    /home/whattingh/experiment/src/pkg/experiment/experiment_test.go:62 +0x23b
pkg/experiment.TestFunc()
    /home/whattingh/experiment/src/pkg/experiment/experiment_test.go:16 +0x82
testing.tRunner(0xf8400000e0, 0x5f8438, 0x0, 0x0)
    /home/whattingh/go/src/pkg/testing/testing.go:271 +0x6f
created by testing.RunTests
    /home/whattingh/go/src/pkg/testing/testing.go:350 +0x76e


*********** RESULT 3 ***********
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
    [signal 0xb code=0x1 addr=0x0 pc=0x47d349]

    goroutine 3 [running]:
    testing._func_003(0x7f04e31b7fa8, 0x7f04e31b7100, 0x7f04e31b7728, 0x7f04e31b7688)
        /home/whattingh/go/src/pkg/testing/testing.go:266 +0xf3
    ----- stack segment boundary -----
    encoding/gob.catchError(0xf84009b090, 0x7f04e31b7100)
        /home/whattingh/go/src/pkg/encoding/gob/error.go:38 +0x9a
    ----- stack segment boundary -----
    encoding/gob.catchError(0xf84009b090, 0x7f04e31b7100)
        /home/whattingh/go/src/pkg/encoding/gob/error.go:38 +0x9a
    ----- stack segment boundary -----
    encoding/gob._func_013(0xf84006b5e0, 0xf840048b60, 0xf84006b5e8, 0x4730fb, 0xf8400a31e0, ...)
        /home/whattingh/go/src/pkg/encoding/gob/encode.go:577 +0xed
    encoding/gob.(*Encoder).encodeStruct(0xf84009b000, 0xf840154300, 0xf840048b50, 0xf84015a480, 0x5205f8, ...)
        /home/whattingh/go/src/pkg/encoding/gob/encode.go:370 +0xf2
    encoding/gob.(*Encoder).encode(0xf84009b000, 0xf840154300, 0x5205f8, 0xf84015a480, 0x196, ...)
        /home/whattingh/go/src/pkg/encoding/gob/encode.go:727 +0x18d
    encoding/gob.(*Encoder).encodeInterface(0xf84009b000, 0xf84009b030, 0x4c02e0, 0xf8400bcc50, 0x146, ...)
        /home/whattingh/go/src/pkg/encoding/gob/encode.go:457 +0x590
    encoding/gob._func_017(0xf840048920, 0x472fee, 0xf84005ee00, 0xf84009f1e0, 0xf8400bcc50, ...)
        /home/whattingh/go/src/pkg/encoding/gob/encode.go:622 +0x17c
    encoding/gob.(*Encoder).encodeSingle(0xf84009b000, 0xf84009b030, 0xf840048910, 0xf8400bcc50, 0x4c02e0, ...)


Which compiler are you using (5g, 6g, 8g, gccgo)?
6g

Which operating system are you using?
linux

Which revision are you using?  (hg identify)
2bd4bf330ca5+ tip


Please provide any additional information below.
Most of the time i get Result 2. 

I did this experiment as I have big code that gave panics that did not make sense. 

I have a feeling the main problem is in gob but that is speculation.

Attachments:

  1. experiment_test.go (2251 bytes)
@gopherbot
Copy link
Author

@gopherbot gopherbot commented Mar 2, 2012

Comment 1 by werner.hattingh:

Oops here is correct file

Attachments:

  1. experiment_test.go (2239 bytes)
@rsc
Copy link
Contributor

@rsc rsc commented Mar 2, 2012

Comment 2:

Probably a runtime bug, but possibly a gob bug.

Labels changed: added priority-go1, removed priority-triage.

Owner changed to builder@golang.org.

Status changed to Accepted.

@rsc
Copy link
Contributor

@rsc rsc commented Mar 7, 2012

Comment 3:

Reproduced on OS X after s;@/;/tmp/;.

Labels changed: added go1-must.

Owner changed to @rsc.

@rsc
Copy link
Contributor

@rsc rsc commented Mar 7, 2012

Comment 4:

This is a standalone program (a slight edit of the one in the report) that I believe
serializes all the gob calls across the goroutines.  It moves all the network calls to
init time.  So the main part of the program is just doing gob over a Unix socket: the
sender does a gob write, then ch <- 0, the receiver does <-ch, then does a gob
read.  I don't know how it could be less concurrent.
And yet it still crashes.  I am starting to wonder if this is gob's fault.  Sent to
Dmitriy to see if automated tools can tell us anything.

Attachments:

  1. gobbug.go (2309 bytes)
@dvyukov
Copy link
Member

@dvyukov dvyukov commented Mar 7, 2012

Comment 5:

I think it's single-threaded memory corruption...
@dvyukov
Copy link
Member

@dvyukov dvyukov commented Mar 7, 2012

Comment 6:

I do not have enough knowledge about gob, but the error seems to be happening here:
#0  encoding/gob.(*Decoder).decodeInterface (dec=0xf8400a0000, ityp=...,
state=0xf84009df60, p=1066226048304, indir=1) at src/pkg/encoding/gob/decode.go:711
#1  0x000000000047fd4b in encoding/gob._func_005 (&t=void, i=0xf84009df00,
state=0xf84009df60, p=0xf840065d30) at src/pkg/encoding/gob/decode.go:892
#2  0x000000f8400ae262 in ?? ()
#3  0x000000f8400ad300 in ?? ()
#4  0x000000000046f2d6 in encoding/gob.(*Decoder).decodeSingle (dec=0xf8400a0000,
engine=0xf8400ab480, ut=0xf84009d180, basep=1066226048304) at
src/pkg/encoding/gob/decode.go:486
#5  0x000000000047401b in encoding/gob.(*Decoder).decodeValue (dec=0xf8400a0000,
wireId=8, val=...) at src/pkg/encoding/gob/decode.go:1230
#6  0x00000000004750cb in encoding/gob.(*Decoder).DecodeValue (dec=0xf8400a0000, v=...,
noname=void) at src/pkg/encoding/gob/decoder.go:208
#7  0x0000000000474f47 in encoding/gob.(*Decoder).Decode (dec=0xf8400a0000,
e="(*interface {})0xf8400ad2e0", noname=void) at src/pkg/encoding/gob/decoder.go:185
#8  0x0000000000424124 in tmp.requestResponse (enc=0xf84009f000, dec=0xf8400a0000,
e=void, noname=void) at src/pkg/tmp/tmp_test.go:88
#9  0x0000000000423f90 in tmp.Client (x=3000, addr="/tmp/experiment.socket") at
src/pkg/tmp/tmp_test.go:71
The source line is:
        *(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData()
with the comment "This is horribly unsafe".
During decoding of the nil error pointer (request response).
Perhaps the type name should not be empty string since it is the error. Or perhaps the
value is just written into wrong location.
@dvyukov
Copy link
Member

@dvyukov dvyukov commented Mar 7, 2012

Comment 7:

Forgot to mention, the source line overwrites beginning on the next (or previous) memory
block, perhaps there is space for 1 word, but it overwrites 2.
The instruction is:
   0x0000000000470679 <+305>: lea    0xe0(%rsp),%rsi
   0x0000000000470681 <+313>: lea    (%rsp),%rdi
   0x0000000000470685 <+317>: movsq  %ds:(%rsi),%es:(%rdi)
   0x0000000000470687 <+319>: movsq  %ds:(%rsi),%es:(%rdi)
   0x0000000000470689 <+321>: movsq  %ds:(%rsi),%es:(%rdi)
   0x000000000047068b <+323>: callq  0x4ade11 <reflect.Value.InterfaceData>
   0x0000000000470690 <+328>: lea    0x18(%rsp),%rsi
   0x0000000000470695 <+333>: lea    0x148(%rsp),%rdi
   0x000000000047069d <+341>: movsq  %ds:(%rsi),%es:(%rdi)
   0x000000000047069f <+343>: movsq  %ds:(%rsi),%es:(%rdi)
   0x00000000004706a1 <+345>: mov    0x190(%rsp),%rax
   0x00000000004706a9 <+353>: mov    %rax,%rdi
   0x00000000004706ac <+356>: lea    0x148(%rsp),%rsi
   0x00000000004706b4 <+364>: movsq  %ds:(%rsi),%es:(%rdi)
=> 0x00000000004706b6 <+366>:  movsq  %ds:(%rsi),%es:(%rdi)
   0x00000000004706b8 <+368>: add    $0x168,%rsp
   0x00000000004706bf <+375>: retq   
Btw, these instructions doubled 2 or 3 times look a bit strange...
@dvyukov
Copy link
Member

@dvyukov dvyukov commented Mar 7, 2012

Comment 8:

> Btw, these instructions doubled 2 or 3 times look a bit strange...
Ah, OK, the instructions modify rsi/rdi.
So it's the store to the second word, perhaps it's missing indirection, the code below
does:
p = allocate(ityp, p, 1)
before writing to the 'p'. But here we write directly to 'p'.
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Mar 7, 2012

Comment 9:

The "nil interface value" case is forgetting to handle the case indir > 0.  Try copying
the lines
    // Allocate the destination interface value.
    if indir > 0 {
        p = allocate(ityp, p, 1) // All but the last level has been allocated by dec.Indirect
    }
to just after the "horribly unsafe and special" comment.
@dvyukov
Copy link
Member

@dvyukov dvyukov commented Mar 7, 2012

Comment 10:

It fixes the issue
http://golang.org/cl/5758069
@dvyukov
Copy link
Member

@dvyukov dvyukov commented Mar 7, 2012

Comment 11:

Owner changed to @dvyukov.

@rsc
Copy link
Contributor

@rsc rsc commented Mar 7, 2012

Comment 12:

(Pending review.)

Status changed to Started.

@dvyukov
Copy link
Member

@dvyukov dvyukov commented Mar 7, 2012

Comment 13:

This issue was closed by revision c8b1f85.

Status changed to Fixed.

@gopherbot gopherbot added fixed labels Mar 7, 2012
@rsc rsc added this to the Go1 milestone Apr 10, 2015
@rsc rsc removed priority-go1 labels Apr 10, 2015
@golang golang locked and limited conversation to collaborators Jun 24, 2016
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.