致命错误:Cgo

时间:2016-04-13 07:11:06

标签: memory-management go garbage-collection cgo

我的程序在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的空间?

0 个答案:

没有答案