Yeah, source code and dumping memory seems to be the only and right way to know 
exactly why. 


Thanks for your responses

YUU


> On Mar 9, 2020, at 11:39 PM, Leszek Kubik <leszek.ku...@gmail.com> wrote:
> 
> To understand (make a best guess) a race condition case you need to dump the 
> physical memory and analyze it against the internal code.
> 
> But what’s the value of doing that for you?
> 
> I’ve done numerous race condition analysis. It’s almost never an obvious 
> answer as data gets overwritten in memory so the chronological order is 
> always lost, you can extract only scraps of it and from that you switch to 
> the source/compiled code to figure out where is the race condition or 
> undefined behavior. In your case it’s obvious so don’t waste time on it.
> 
> 
> 
> On Mon, 9 Mar 2020 at 16:16, Yuu LongXue <longxue...@gmail.com 
> <mailto:longxue...@gmail.com>> wrote:
> Hi all,
> 
> Slice is not thread safe for write operation if without lock, this is true 
> and I know this feature. but recently, I got a panic which caused by writing 
> a slice concurrently with out lock occasionally and I can't figure out why.
> 
> ### the process as below:
>   1. define a slice: var x []string
>   2. append to x concurrently without lock in multi goroutines
>   3. wait all goroutines to be done
>   4. iterate the x slice, panic occurred when read some element with index 
> <strong>i (i > 0 && i < len(x)-1)</strong> in the x
> 
> ### the question is:
> In this case, the element with index 0 and index len(x) - 1 is ok to read, 
> but it exists a <strong>x[i](i > 0 && i < len(x)-1)</strong> that can't be 
> read and it will lead to panic[invalid memory address or nil pointer 
> dereference];
> 
> I know that some data by the write operation missed, but how could the panic 
> occur? I have tried my best to know why, but I still can't figure out;
> <strong>so could anyone tell me why the element in x has a invalid address?
> maybe it was collected by gc or not initialized yet and why?<strong>
> 
> ### code
> ```
> func TestConcurrentWriteSlice(t *testing.T) {
> // panic do not occurred for each running, so I repeat until it occurred
>         for i := 0; i < 100; i++ {
>                 testConcurrentWriteSlice()
>         }
> }
> 
> func testConcurrentWriteSlice() {
>         var strs []string
> 
>   // write concurrently here
>         var wg sync.WaitGroup
>         for x := 0; x < 1000; x++ {
>                 wg.Add(1)
>                 go func() {
>                         defer func() { wg.Done() }()
>                         time.Sleep(2 * time.Second)
>                         for i := 65; i < 91; i++ {
>                                 strs = append(strs, string(i))
>                         }
>                 }()
>         }
>         wg.Wait()
> 
>         l := len(strs)
>         log.Printf("strs len: %v f=%v l=%v", l, strs[0], strs[l-1])
>         for i := 0; i < l; i++ {
>                 log.Printf("strs len=%v i=%v first=%v last=%v 
> &current[i]=%v", l, i, strs[0], strs[l-1], &strs[i])
> 
>     // panic here
>                 log.Printf("strs len=%v i=%v first=%v last=%v current=%v", l, 
> i, strs[0], strs[l-1], strs[i])
>         }
> }
> ```
> 
> ### output log
> ```
> 2020/03/09 14:39:08 strs len=2607 i=519 first=A last=Z 
> &current[i]=0xc000606070
> 2020/03/09 14:39:08 strs len=2607 i=519 first=A last=Z current=
> 2020/03/09 14:39:08 strs len=2607 i=520 first=A last=Z 
> &current[i]=0xc000606080
> 2020/03/09 14:39:08 strs len=2607 i=520 first=A last=Z current=
> 2020/03/09 14:39:08 strs len=2607 i=521 first=A last=Z 
> &current[i]=0xc000606090
> 2020/03/09 14:39:08 strs len=2607 i=521 first=A last=Z current=
> 2020/03/09 14:39:08 strs len=2607 i=522 first=A last=Z 
> &current[i]=0xc0006060a0
> 2020/03/09 14:39:08 strs len=2607 i=522 first=A last=Z current=
> 2020/03/09 14:39:08 strs len=2607 i=523 first=A last=Z 
> &current[i]=0xc0006060b0
> --- FAIL: TestConcurrentWriteSlice (19.72s)
> panic: runtime error: invalid memory address or nil pointer dereference 
> [recovered]
>         panic: runtime error: invalid memory address or nil pointer 
> dereference
> [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x105aa93]
> 
> goroutine 33 [running]:
> testing.tRunner.func1(0xc0000d8100)
>         /usr/local/go/src/testing/testing.go:874 +0x3a3
> panic(0x1127f20, 0x12494b0)
>         /usr/local/go/src/runtime/panic.go:679 +0x1b2
> fmt.(*buffer).writeString(...)
>         /usr/local/go/src/fmt/print.go:82
> fmt.(*fmt).padString(0xc000082040, 0x0, 0x115ced0)
>         /usr/local/go/src/fmt/format.go:110 +0x8c
> fmt.(*fmt).fmtS(0xc000082040, 0x0, 0x115ced0)
>         /usr/local/go/src/fmt/format.go:359 +0x61
> fmt.(*pp).fmtString(0xc000082000, 0x0, 0x115ced0, 0x76)
>         /usr/local/go/src/fmt/print.go:447 +0x131
> fmt.(*pp).printArg(0xc000082000, 0x111c3a0, 0xc00011ed80, 0x76)
>         /usr/local/go/src/fmt/print.go:698 +0x877
> fmt.(*pp).doPrintf(0xc000082000, 0x115b38e, 0x2c, 0xc0000c9ef8, 0x5, 0x5)
>         /usr/local/go/src/fmt/print.go:1030 +0x15b
> fmt.Sprintf(0x115b38e, 0x2c, 0xc000840ef8, 0x5, 0x5, 0x1, 0xc00011ed80)
>         /usr/local/go/src/fmt/print.go:219 +0x66
> log.Printf(0x115b38e, 0x2c, 0xc000840ef8, 0x5, 0x5)
>         /usr/local/go/src/log/log.go:307 +0x53
> github.com/test/project/util.testConcurrentWriteSlice() 
> <http://github.com/test/project/util.testConcurrentWriteSlice()>
>         /Users/zhangqinxue/work/github/demo/go/project/util/slice_test.go:36 
> +0x323
> github.com/test/project/util.TestConcurrentWriteSlice(0xc0000d8100) 
> <http://github.com/test/project/util.TestConcurrentWriteSlice(0xc0000d8100)>
>         /Users/zhangqinxue/work/github/demo/go/project/util/slice_test.go:12 
> +0x2a
> testing.tRunner(0xc0000d8100, 0x115caf0)
>         /usr/local/go/src/testing/testing.go:909 +0xc9
> created by testing.(*T).Run
>         /usr/local/go/src/testing/testing.go:960 +0x350
> ```
> 
> Thanks
> 
> YUU
> 
> -- 
> 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 
> <mailto:golang-nuts%2bunsubscr...@googlegroups.com>.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/122CE4C2-A82A-4819-BFBD-E6E98A71BF7F%40gmail.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/122CE4C2-A82A-4819-BFBD-E6E98A71BF7F%40gmail.com>.

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/17AC7561-2A5D-46CA-9DCC-2F737BCC91DC%40gmail.com.

Reply via email to