It seems like you start your post by acknowledging that you have a race. 
But you are wondering why that race is causing a panic? Is that a correct 
assessment of you post?

A race condition can cause all sorts of bad behavior. Some may behave 
"normally" 99.99999% of the time, then cause an incorrect result. Or they 
may panic all the time, or some of the time. Or worse, they can cause a 
panic, or some other bad behavior, in a seemingly unrelated part of the 
code, long after the race condition occurred. While it may be *interesting *to 
try to understand how a particular race caused a particular behavior, it is 
not generally *useful *to do so. There is no such thing as a "safe" race in 
Go. You should always take great care to strictly follow the "rules" to 
avoid races. You should always fix a race condition as soon as you find it. 

This is an interesting read on the topic of race conditions: 
https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong



On Monday, March 9, 2020 at 11:17:10 AM UTC-4, Yuu LongXue 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() 
>         /Users/zhangqinxue/work/github/demo/go/project/util/slice_test.go:36 
> +0x323 
> 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/34ef4421-3943-4f82-afdc-d95990fd8702%40googlegroups.com.

Reply via email to