我的程序在1000次内崩溃了1次。这是调试信息和堆栈:
437
new map 0 -603977536
address&{[<nil> 0x7fafdc0009f0 0x7fafdc000b00]} 0x7fafdc0008c0 0x7fafdc0008c8 0x7fafdc0008d0
&{1 0 0x7fafdc000900} &{1 0 0x7fafdc000a10} &{1 0 0x7fafdc000b20}
rgc map finish
438
new map 0 -603977536
address&{[<nil> 0x7fafdc0009f0 0x7fafdc000b00]} 0x7fafdc0008c0 0x7fafdc0008c8 0x7fafdc0008d0
&{1 0 0x7fafdc000900} &{1 0 0x7fafdc000a10} &{1 0 0x7fafdc000b20}
rgc map finish
439
new map 0 -603977536
address&{[<nil> 0x7fafdc0009f0 0x7fafdc000b00]} 0x7fafdc0008c0 0x7fafdc0008c8 0x7fafdc0008d0
&{1 0 0x7fafdc000900} &{1 0 0x7fafdc000a10} &{1 0 0x7fafdc000b20}
rgc map finish
440
new map 0 -603977536
address&{[<nil> 0x7fafdc0009f0 0x7fafdc000b00]} 0x7fafdc0008c0 0x7fafdc0008c8 0x7fafdc0008d0
&{1 0 0x7fafdc000900} &{1 0 0x7fafdc000a10} &{1 0 0x7fafdc000b20}
rgc map finish
441
new map 0 -536868672
fatal error: bad pointer in write barrier
runtime stack:
runtime.throw(0x53d200, 0x1c)
/home/map/.jumbo/lib/go/src/runtime/panic.go:530 +0x90
runtime.writebarrierptr_nostore.func1()
/home/map/.jumbo/lib/go/src/runtime/mbarrier.go:157 +0x2c
runtime.systemstack(0xc820024a00)
/home/map/.jumbo/lib/go/src/runtime/asm_amd64.s:291 +0x79
runtime.mstart()
/home/map/.jumbo/lib/go/src/runtime/proc.go:1048
goroutine 1 [running]:
runtime.systemstack_switch()
/home/map/.jumbo/lib/go/src/runtime/asm_amd64.s:245 fp=0xc82009ebd8 sp=0xc82009ebd0
runtime.writebarrierptr_nostore(0xc82030e010, 0x20)
/home/map/.jumbo/lib/go/src/runtime/mbarrier.go:157 +0x83 fp=0xc82009ebf0 sp=0xc82009ebd8
runtime.heapBitsBulkBarrier(0xc82030e000, 0x18)
/home/map/.jumbo/lib/go/src/runtime/mbitmap.go:437 +0x201 fp=0xc82009ec88 sp=0xc82009ebf0
runtime.typedmemmove(0x4fa700, 0xc82030e000, 0x7fafe00008c0)
/home/map/.jumbo/lib/go/src/runtime/mbarrier.go:197 +0x98 fp=0xc82009ecb8 sp=0xc82009ec88
reflect.typedmemmove(0x4fa700, 0xc82030e000, 0x7fafe00008c0)
/home/map/.jumbo/lib/go/src/runtime/mbarrier.go:202 +0x35 fp=0xc82009ecd8 sp=0xc82009ecb8
reflect.packEface(0x4fa700, 0x7fafe00008c0, 0x199, 0x0, 0x0)
/home/map/.jumbo/lib/go/src/reflect/value.go:113 +0x120 fp=0xc82009ed48 sp=0xc82009ecd8
reflect.valueInterface(0x4fa700, 0x7fafe00008c0, 0x199, 0x1, 0x0, 0x0)
/home/map/.jumbo/lib/go/src/reflect/value.go:938 +0x1ec fp=0xc82009eda0 sp=0xc82009ed48
reflect.Value.Interface(0x4fa700, 0x7fafe00008c0, 0x199, 0x0, 0x0)
/home/map/.jumbo/lib/go/src/reflect/value.go:908 +0x48 fp=0xc82009edd8 sp=0xc82009eda0
fmt.(*pp).printValue(0xc82040b380, 0x4fa700, 0x7fafe00008c0, 0x199, 0x7faf00000076, 0x1, 0x0)
/home/map/.jumbo/lib/go/src/fmt/print.go:842 +0x372 fp=0xc82009eec8 sp=0xc82009edd8
fmt.(*pp).printReflectValue(0xc82040b380, 0x4cc980, 0x7fafe00008c0, 0x16, 0x76, 0x0, 0xc82001cd00)
/home/map/.jumbo/lib/go/src/fmt/print.go:1009 +0x351e fp=0xc82009f680 sp=0xc82009eec8
fmt.(*pp).printArg(0xc82040b380, 0x4cc980, 0x7fafe00008c0, 0x76, 0x0, 0xc82009f800)
/home/map/.jumbo/lib/go/src/fmt/print.go:810 +0x540 fp=0xc82009f808 sp=0xc82009f680
fmt.(*pp).doPrint(0xc82040b380, 0xc82009fdf8, 0x2, 0x2, 0x400000)
/home/map/.jumbo/lib/go/src/fmt/print.go:1273 +0x24d fp=0xc82009f908 sp=0xc82009f808
fmt.Fprint(0x7faff5a401c0, 0xc820036010, 0xc82009fdf8, 0x2, 0x2, 0x40d75e, 0x0, 0x0)
/home/map/.jumbo/lib/go/src/fmt/print.go:222 +0x67 fp=0xc82009f950 sp=0xc82009f908
fmt.Print(0xc82009fdf8, 0x2, 0x2, 0x4d6ac0, 0x0, 0x0)
/home/map/.jumbo/lib/go/src/fmt/print.go:232 +0x73 fp=0xc82009f9a8 sp=0xc82009f950
services/newrgc.GetRgcService(0x54cb60, 0x49, 0xc8200aa330, 0x0, 0x0)
/home/map/zhanghuaizhi/tmpwork/2/nbserver/src/services/newrgc/mrgc.go:78 +0x390 fp=0xc82009fea0 sp=0xc82009f9a8
main.main()
/home/map/zhanghuaizhi/tmpwork/2/nbserver/src/services/newrgc/test/ttt.go:219 +0x163 fp=0xc82009ff40 sp=0xc82009fea0
runtime.main()
/home/map/.jumbo/lib/go/src/runtime/proc.go:188 +0x2b0 fp=0xc82009ff90 sp=0xc82009ff40
runtime.goexit()
/home/map/.jumbo/lib/go/src/runtime/asm_amd64.s:1998 +0x1 fp=0xc82009ff98 sp=0xc82009ff90
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/home/map/.jumbo/lib/go/src/runtime/asm_amd64.s:1998 +0x1
deug信息在堆栈日志之前。 437
表示第437个循环,new map 0 -603977536
以C代码(NewRgcMap
打印,详细信息可在以下内容中找到),接下来的两行
Go代码中印有address&{[<nil> 0x7fafdc0009f0 0x7fafdc000b00]} 0x7fafdc0008c0 0x7fafdc0008c8 0x7fafdc0008d0
&{1 0 0x7fafdc000900} &{1 0 0x7fafdc000a10} &{1 0 0x7fafdc000b20}
(GO代码第78和80行)。
从堆栈信息中,我们可以发现错误发生在第78行。现在这里是Go代码(mrgc.go)
30 type RgcService struct {
31 maps *C.struct_CRgcMap
32 }
74 func GetRgcService(cfgFile string) (svc *RgcService, err error) {
75 svc = new(RgcService)
76 // Init the skip list
77 C.NewRgcMap(&svc.maps)
78 fmt.Print("address", svc.maps)
79 //fmt.Println("\t", svc.maps.sl[0], svc.maps.sl[1], svc.maps.sl[2])
80 fmt.Println("\t", &svc.maps.sl[0], &svc.maps.sl[1], &svc.maps.sl[2])
81 C.skiplist_init(unsafe.Pointer(&svc.maps.sl[0]))
82 C.skiplist_init(unsafe.Pointer(&svc.maps.sl[1]))
83 C.skiplist_init(unsafe.Pointer(&svc.maps.sl[2]))
84 fmt.Println("\t", svc.maps.sl[0], svc.maps.sl[1], svc.maps.sl[2])
所以,我可能会因为C.NewRgcMap(&svc.maps)
的失败而猜错。但是,在我的c代码中,funciotn NewRgcMap
是:
39 void NewRgcMap(CRgcMap** rgcmap) {
40 *rgcmap = NULL;
41 printf("new map %d\t", *rgcmap);
42 *rgcmap = (CRgcMap*)malloc(sizeof(CRgcMap));
43 printf("%d\n", *rgcmap);
44 while(*rgcmap == NULL) {
45 *rgcmap = (CRgcMap*)malloc(sizeof(CRgcMap));
46 }
表示必须正确分配rgcmap
。
另一点是,从我的调试信息中,我发现当第一次将日志new map 0 -603977536
更改为new map -536868672
时程序崩溃了。更详细地说,程序崩溃时调试日志完全相同。 new map 0 xxxxx1
显示了一些时间,然后当它变为new map 0 xxxxx2
时,它可能会崩溃(大多数情况下,它不会崩溃)
如何解释这次崩溃?此外,我使用valgrind
来测试C代码(以下是我的C测试代码)
int main() {
CRgcMap map;
int num = 0;
for(num = 0; num < 10000; num++) {
skiplist_init(&map.sl[0]);
skiplist_init(&map.sl[1]);
skiplist_init(&map.sl[2]);
int i = 0;
for(i = 0; i < 100; i++) {
skiplist_insert(map.sl[0], i, i);
skiplist_insert(map.sl[1], i, i);
//skiplist_insert(map.sl[2], i, i);
}
skiplist_test(map.sl[0]);
skiplist_test(map.sl[1]);
skiplist_test(map.sl[2]);
}
}
valgrind
的报告显示没有内存泄漏,一切正常。但是为什么它在使用Golang时会崩溃? Go的GC有什么相关的吗?或者C分配的地址超出了Golang的空间?