Re: [go-nuts] why my program will panic?
* sheepbao [180814 10:53]: > Thank you for your detailed answer. > I thought it would crash in this line (b.Z = "zz") of code. But it dose not > happen and the program print "zz". > I don't understand why this program crash in return, not in b.Z = "zz". > Because I agree with your opinion, The field Z of (*b) is beyond the > memory that was allocated > on the heap or reserved on the stack for a. It does not crash when assigning to b.Z because b.Z references valid, writable memory. It overwrites what some other part of the code wrote there for a different purpose. It is not until the incorrect value is read and used for the original intended purpose that incorrect behavior can be noticed. If nothing ever reads from that location afterwards, than no incorrect behavior can be observed. It might crash when assigning to b.Z if that memory location is not writable or is not within the program's address space. This could happen, for instance, if the memory allocated for a were at the very end of the program's address space. This is extremely unlikely under most circumstances. Once you use unsafe to convert a pointer from one type to another, you become responsible for ensuring that your use is appropriate; the compiler no longer attempts to keep track of the memory to which the unsafe pointer points. ...Marvin -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] why my program will panic?
Thank you for your detailed answer. I thought it would crash in this line (b.Z = "zz") of code. But it dose not happen and the program print "zz". I don't understand why this program crash in return, not in b.Z = "zz". Because I agree with your opinion, The field Z of (*b) is beyond the memory that was allocated on the heap or reserved on the stack for a. On Tuesday, August 14, 2018 at 9:57:05 PM UTC+8, Marvin Renich wrote: > > * sheepbao > [180813 23:45]: > > go version > > go version go1.10.2 darwin/amd64 > > > > test code: > > > > func TestPoint(t *testing.T) { > > type A struct { > > X int > > Y string > > } > > type B struct { > > X int > > Y string > > Z string > > } > > > > a := A{X: 2, Y: "yy"} > > b := (*B)(unsafe.Pointer()) > > b.Z = "zz" > > > > fmt.Printf(" z: %v\n", b.Z) > > return > > } > > Enough bytes are allocated for a (of type A). It doesn't matter whether > they are on the stack or on the heap. Now you use unsafe to make b a > pointer to type B that points to the same memory location where a was > allocated. The field Z of (*b) is beyond the memory that was allocated > on the heap or reserved on the stack for a. Neither the compiler (for > stack-reserved a) nor the runtime (for heap-allocated a) has made any > provision for ensuring that the memory immediately beyond a is not used > for anything else. Writing to b.Z overwrites memory to which b has no > claim. > > Both this code and the change in your subsequent message are simply > wrong. Whether it crashes or not depends on the legitimate "owner" of > the memory at b.Z. If it is a return address on the stack, a crash is > almost certain. If it is memory on the heap that has not been allocated > yet, and will never be allocated in such a simple program, you might not > see any evidence that the code was written incorrectly. > > ...Marvin > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] why my program will panic?
* sheepbao [180813 23:45]: > go version > go version go1.10.2 darwin/amd64 > > test code: > > func TestPoint(t *testing.T) { > type A struct { > X int > Y string > } > type B struct { > X int > Y string > Z string > } > > a := A{X: 2, Y: "yy"} > b := (*B)(unsafe.Pointer()) > b.Z = "zz" > > fmt.Printf(" z: %v\n", b.Z) > return > } Enough bytes are allocated for a (of type A). It doesn't matter whether they are on the stack or on the heap. Now you use unsafe to make b a pointer to type B that points to the same memory location where a was allocated. The field Z of (*b) is beyond the memory that was allocated on the heap or reserved on the stack for a. Neither the compiler (for stack-reserved a) nor the runtime (for heap-allocated a) has made any provision for ensuring that the memory immediately beyond a is not used for anything else. Writing to b.Z overwrites memory to which b has no claim. Both this code and the change in your subsequent message are simply wrong. Whether it crashes or not depends on the legitimate "owner" of the memory at b.Z. If it is a return address on the stack, a crash is almost certain. If it is memory on the heap that has not been allocated yet, and will never be allocated in such a simple program, you might not see any evidence that the code was written incorrectly. ...Marvin -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] why my program will panic?
I just want to research how golang func stack work. On Tuesday, August 14, 2018 at 12:46:59 PM UTC+8, kortschak wrote: > > Why would you expect this to work? > > On Mon, 2018-08-13 at 20:44 -0700, sheepbao wrote: > > go version > > go version go1.10.2 darwin/amd64 > > > > test code: > > > > func TestPoint(t *testing.T) { > > type A struct { > > X int > > Y string > > } > > type B struct { > > X int > > Y string > > Z string > > } > > > > a := A{X: 2, Y: "yy"} > > b := (*B)(unsafe.Pointer()) > > b.Z = "zz" > > > > fmt.Printf(" z: %v\n", b.Z) > > return > > } > > > > > > > > panic info: > > === RUN TestPoint > > z: zz > > runtime: unexpected return pc for runtime.sigpanic called from 0x2 > > stack: frame={sp:0xc42004cf58, fp:0xc42004cfa8} > > stack=[0xc42004c000,0xc42004d000) > > 00c42004ce58: 00c42004ce88 010514bb > > > > 00c42004ce68: 00c4200c00f0 00c4200b8020 > > 00c42004ce78: 0007 0020 > > 00c42004ce88: 00c42004cf28 01027ee9 > > > > 00c42004ce98: 01136758 > > 00c42004cea8: 00c42008e6b0 00080008 > > 00c42004ceb8: 00c420033720 > > 00c42004cec8: 010973c2 00c420066600 > > 00c42004ced8: 00c42009a008 00c42008e6a0 > > 00c42004cee8: 00c42008e680 00c420066628 > > 00c42004cef8: 00c420066620 00c42004ce68 > > 00c42004cf08: 01108ea0 011d4f80 > > 00c42004cf18: 0001 > > 00c42004cf28: 00c42004cf48 01026f5e > > > > 00c42004cf38: 01108ea0 011d4f80 > > 00c42004cf48: 00c42004cf98 0103b7aa > > > > 00c42004cf58: <00c420066600 0001 > > 00c42004cf68: 010fe240 > > 00c42004cf78: 00c420082460 00c420066600 > > 00c42004cf88: 0112d8f6 0002 > > 00c42004cf98: 0112d8f8 !0002 > > 00c42004cfa8: >00c4200c00f0 000aace2 > > 00c42004cfb8: 011dc160 > > 00c42004cfc8: 01053ac1 > > 00c4200c00f0 > > 00c42004cfd8: 01136150 > > 00c42004cfe8: > > 00c42004cff8: > > fatal error: unknown caller pc > > > > runtime stack: > > runtime.throw(0x112fd13, 0x11) > > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/panic.go > > :616 > > +0x81 > > runtime.gentraceback(0x, 0x, 0x0, > > 0xc420066600, 0x0, 0x0, 0x7fff, 0x1136348, 0x7ffeefbff088, 0x0, > > ...) > > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/tracebac > > k.go:257 > > +0x1bdb > > runtime.copystack(0xc420066600, 0x1000, 0x1) > > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/stack.go > > :891 > > +0x270 > > runtime.newstack() > > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/stack.go > > :1063 > > +0x30f > > runtime.morestack() > > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/asm_amd6 > > 4.s:492 > > +0x89 > > > > goroutine 19 [copystack]: > > fmt.(*pp).argNumber(0xc4200c6000, 0x0, 0x112db26, 0x5, 0x1, 0x1, 0x0, > > 0x0, > > 0x0) > > /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:926 > > > > +0x112 fp=0xc42004cb48 sp=0xc42004cb40 pc=0x109d9a2 > > fmt.(*pp).doPrintf(0xc4200c6000, 0x112db26, 0x5, 0xc42004ccc8, 0x1, > > 0x1) > > /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:101 > > 4 > > +0x1ca fp=0xc42004cc30 sp=0xc42004cb48 pc=0x109deba > > fmt.Sprintf(0x112db26, 0x5, 0xc4200334c8, 0x1, 0x1, 0xc42008e6d8, > > 0xc42008e6e0) > > /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:203 > > +0x66 > > fp=0xc42004cc88 sp=0xc42004cc30 pc=0x1097466 > > testing.fmtDuration(0xa388, 0x3, 0xc420026570) > > /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing. > > go:438 > > +0xdf fp=0xc42004cce8 sp=0xc42004cc88 pc=0x10ae90f > > testing.(*T).report(0xc4200c00f0) > > /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing. > > go:997 > > +0x57 fp=0xc42004cdf8 sp=0xc42004cce8 pc=0x10afcf7 > > testing.tRunner.func1(0xc4200c00f0) > > /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing. > > go:741 > > +0x285 fp=0xc42004ce68 sp=0xc42004cdf8 pc=0x10b2e75 > > runtime.call32(0x0, 0x1136758, 0xc42008e6b0, 0x80008) > > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/asm_amd6 > > 4.s:585 > > +0x3b fp=0xc42004ce98 sp=0xc42004ce68 pc=0x10514bb > > panic(0x1108ea0, 0x11d4f80) > > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/panic.go > > :502 > > +0x229 fp=0xc42004cf38 sp=0xc42004ce98
Re: [go-nuts] why my program will panic?
Why would you expect this to work? On Mon, 2018-08-13 at 20:44 -0700, sheepbao wrote: > go version > go version go1.10.2 darwin/amd64 > > test code: > > func TestPoint(t *testing.T) { > type A struct { > X int > Y string > } > type B struct { > X int > Y string > Z string > } > > a := A{X: 2, Y: "yy"} > b := (*B)(unsafe.Pointer()) > b.Z = "zz" > > fmt.Printf(" z: %v\n", b.Z) > return > } > > > > panic info: > === RUN TestPoint > z: zz > runtime: unexpected return pc for runtime.sigpanic called from 0x2 > stack: frame={sp:0xc42004cf58, fp:0xc42004cfa8} > stack=[0xc42004c000,0xc42004d000) > 00c42004ce58: 00c42004ce88 010514bb > > 00c42004ce68: 00c4200c00f0 00c4200b8020 > 00c42004ce78: 0007 0020 > 00c42004ce88: 00c42004cf28 01027ee9 > > 00c42004ce98: 01136758 > 00c42004cea8: 00c42008e6b0 00080008 > 00c42004ceb8: 00c420033720 > 00c42004cec8: 010973c2 00c420066600 > 00c42004ced8: 00c42009a008 00c42008e6a0 > 00c42004cee8: 00c42008e680 00c420066628 > 00c42004cef8: 00c420066620 00c42004ce68 > 00c42004cf08: 01108ea0 011d4f80 > 00c42004cf18: 0001 > 00c42004cf28: 00c42004cf48 01026f5e > > 00c42004cf38: 01108ea0 011d4f80 > 00c42004cf48: 00c42004cf98 0103b7aa > > 00c42004cf58: <00c420066600 0001 > 00c42004cf68: 010fe240 > 00c42004cf78: 00c420082460 00c420066600 > 00c42004cf88: 0112d8f6 0002 > 00c42004cf98: 0112d8f8 !0002 > 00c42004cfa8: >00c4200c00f0 000aace2 > 00c42004cfb8: 011dc160 > 00c42004cfc8: 01053ac1 > 00c4200c00f0 > 00c42004cfd8: 01136150 > 00c42004cfe8: > 00c42004cff8: > fatal error: unknown caller pc > > runtime stack: > runtime.throw(0x112fd13, 0x11) > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/panic.go > :616 > +0x81 > runtime.gentraceback(0x, 0x, 0x0, > 0xc420066600, 0x0, 0x0, 0x7fff, 0x1136348, 0x7ffeefbff088, 0x0, > ...) > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/tracebac > k.go:257 > +0x1bdb > runtime.copystack(0xc420066600, 0x1000, 0x1) > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/stack.go > :891 > +0x270 > runtime.newstack() > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/stack.go > :1063 > +0x30f > runtime.morestack() > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/asm_amd6 > 4.s:492 > +0x89 > > goroutine 19 [copystack]: > fmt.(*pp).argNumber(0xc4200c6000, 0x0, 0x112db26, 0x5, 0x1, 0x1, 0x0, > 0x0, > 0x0) > /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:926 > > +0x112 fp=0xc42004cb48 sp=0xc42004cb40 pc=0x109d9a2 > fmt.(*pp).doPrintf(0xc4200c6000, 0x112db26, 0x5, 0xc42004ccc8, 0x1, > 0x1) > /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:101 > 4 > +0x1ca fp=0xc42004cc30 sp=0xc42004cb48 pc=0x109deba > fmt.Sprintf(0x112db26, 0x5, 0xc4200334c8, 0x1, 0x1, 0xc42008e6d8, > 0xc42008e6e0) > /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:203 > +0x66 > fp=0xc42004cc88 sp=0xc42004cc30 pc=0x1097466 > testing.fmtDuration(0xa388, 0x3, 0xc420026570) > /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing. > go:438 > +0xdf fp=0xc42004cce8 sp=0xc42004cc88 pc=0x10ae90f > testing.(*T).report(0xc4200c00f0) > /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing. > go:997 > +0x57 fp=0xc42004cdf8 sp=0xc42004cce8 pc=0x10afcf7 > testing.tRunner.func1(0xc4200c00f0) > /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing. > go:741 > +0x285 fp=0xc42004ce68 sp=0xc42004cdf8 pc=0x10b2e75 > runtime.call32(0x0, 0x1136758, 0xc42008e6b0, 0x80008) > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/asm_amd6 > 4.s:585 > +0x3b fp=0xc42004ce98 sp=0xc42004ce68 pc=0x10514bb > panic(0x1108ea0, 0x11d4f80) > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/panic.go > :502 > +0x229 fp=0xc42004cf38 sp=0xc42004ce98 pc=0x1027ee9 > runtime.panicmem() > /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/panic.go > :63 > +0x5e fp=0xc42004cf58 sp=0xc42004cf38 pc=0x1026f5e > runtime: unexpected return pc for runtime.sigpanic called from 0x2 > stack: frame={sp:0xc42004cf58, fp:0xc42004cfa8} > stack=[0xc42004c000,0xc42004d000) > 00c42004ce58: 00c42004ce88 010514bb > > 00c42004ce68: 00c4200c00f0 00c4200b8020 > 00c42004ce78: 0007 0020 > 00c42004ce88:
[go-nuts] why my program will panic?
go version go version go1.10.2 darwin/amd64 test code: func TestPoint(t *testing.T) { type A struct { X int Y string } type B struct { X int Y string Z string } a := A{X: 2, Y: "yy"} b := (*B)(unsafe.Pointer()) b.Z = "zz" fmt.Printf(" z: %v\n", b.Z) return } panic info: === RUN TestPoint z: zz runtime: unexpected return pc for runtime.sigpanic called from 0x2 stack: frame={sp:0xc42004cf58, fp:0xc42004cfa8} stack=[0xc42004c000,0xc42004d000) 00c42004ce58: 00c42004ce88 010514bb 00c42004ce68: 00c4200c00f0 00c4200b8020 00c42004ce78: 0007 0020 00c42004ce88: 00c42004cf28 01027ee9 00c42004ce98: 01136758 00c42004cea8: 00c42008e6b0 00080008 00c42004ceb8: 00c420033720 00c42004cec8: 010973c2 00c420066600 00c42004ced8: 00c42009a008 00c42008e6a0 00c42004cee8: 00c42008e680 00c420066628 00c42004cef8: 00c420066620 00c42004ce68 00c42004cf08: 01108ea0 011d4f80 00c42004cf18: 0001 00c42004cf28: 00c42004cf48 01026f5e 00c42004cf38: 01108ea0 011d4f80 00c42004cf48: 00c42004cf98 0103b7aa 00c42004cf58: <00c420066600 0001 00c42004cf68: 010fe240 00c42004cf78: 00c420082460 00c420066600 00c42004cf88: 0112d8f6 0002 00c42004cf98: 0112d8f8 !0002 00c42004cfa8: >00c4200c00f0 000aace2 00c42004cfb8: 011dc160 00c42004cfc8: 01053ac1 00c4200c00f0 00c42004cfd8: 01136150 00c42004cfe8: 00c42004cff8: fatal error: unknown caller pc runtime stack: runtime.throw(0x112fd13, 0x11) /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/panic.go:616 +0x81 runtime.gentraceback(0x, 0x, 0x0, 0xc420066600, 0x0, 0x0, 0x7fff, 0x1136348, 0x7ffeefbff088, 0x0, ...) /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/traceback.go:257 +0x1bdb runtime.copystack(0xc420066600, 0x1000, 0x1) /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/stack.go:891 +0x270 runtime.newstack() /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/stack.go:1063 +0x30f runtime.morestack() /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/asm_amd64.s:492 +0x89 goroutine 19 [copystack]: fmt.(*pp).argNumber(0xc4200c6000, 0x0, 0x112db26, 0x5, 0x1, 0x1, 0x0, 0x0, 0x0) /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:926 +0x112 fp=0xc42004cb48 sp=0xc42004cb40 pc=0x109d9a2 fmt.(*pp).doPrintf(0xc4200c6000, 0x112db26, 0x5, 0xc42004ccc8, 0x1, 0x1) /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:1014 +0x1ca fp=0xc42004cc30 sp=0xc42004cb48 pc=0x109deba fmt.Sprintf(0x112db26, 0x5, 0xc4200334c8, 0x1, 0x1, 0xc42008e6d8, 0xc42008e6e0) /Users/bao/Documents/reading/golang/go1.10.2/src/fmt/print.go:203 +0x66 fp=0xc42004cc88 sp=0xc42004cc30 pc=0x1097466 testing.fmtDuration(0xa388, 0x3, 0xc420026570) /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing.go:438 +0xdf fp=0xc42004cce8 sp=0xc42004cc88 pc=0x10ae90f testing.(*T).report(0xc4200c00f0) /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing.go:997 +0x57 fp=0xc42004cdf8 sp=0xc42004cce8 pc=0x10afcf7 testing.tRunner.func1(0xc4200c00f0) /Users/bao/Documents/reading/golang/go1.10.2/src/testing/testing.go:741 +0x285 fp=0xc42004ce68 sp=0xc42004cdf8 pc=0x10b2e75 runtime.call32(0x0, 0x1136758, 0xc42008e6b0, 0x80008) /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/asm_amd64.s:585 +0x3b fp=0xc42004ce98 sp=0xc42004ce68 pc=0x10514bb panic(0x1108ea0, 0x11d4f80) /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/panic.go:502 +0x229 fp=0xc42004cf38 sp=0xc42004ce98 pc=0x1027ee9 runtime.panicmem() /Users/bao/Documents/reading/golang/go1.10.2/src/runtime/panic.go:63 +0x5e fp=0xc42004cf58 sp=0xc42004cf38 pc=0x1026f5e runtime: unexpected return pc for runtime.sigpanic called from 0x2 stack: frame={sp:0xc42004cf58, fp:0xc42004cfa8} stack=[0xc42004c000,0xc42004d000) 00c42004ce58: 00c42004ce88 010514bb 00c42004ce68: 00c4200c00f0 00c4200b8020 00c42004ce78: 0007 0020 00c42004ce88: 00c42004cf28 01027ee9 00c42004ce98: 01136758 00c42004cea8: 00c42008e6b0 00080008 00c42004ceb8: 00c420033720 00c42004cec8: 010973c2 00c420066600 00c42004ced8: 00c42009a008 00c42008e6a0 00c42004cee8: 00c42008e680 00c420066628 00c42004cef8: