Re: [go-nuts] why my program will panic?

2018-08-14 Thread Marvin Renich
* 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?

2018-08-14 Thread sheepbao
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?

2018-08-14 Thread Marvin Renich
* 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?

2018-08-13 Thread sheepbao
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?

2018-08-13 Thread Dan Kortschak
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?

2018-08-13 Thread sheepbao
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: