Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Golang:C代码出现死机(致命错误),无法恢复_C_Go - Fatal编程技术网

Golang:C代码出现死机(致命错误),无法恢复

Golang:C代码出现死机(致命错误),无法恢复,c,go,C,Go,我正在将Leptonica C库导入我的Go应用程序,并使用它旋转和裁剪图像 出于某种原因,它随机产生恐慌。我的意思是随机的,因为我只是在这一点上进行测试,所以我在测试过程中使用完全相同的旋转/裁剪指令重复处理完全相同的20幅图像。通常它可以工作,但大约有1/50倍会在图像中随机出现恐慌,尽管通常情况下图像上的恐慌较少(大部分为白色图像) 给出的恐慌是: fatal error: unexpected signal during runtime execution [signal 0xb cod

我正在将Leptonica C库导入我的Go应用程序,并使用它旋转和裁剪图像

出于某种原因,它随机产生恐慌。我的意思是随机的,因为我只是在这一点上进行测试,所以我在测试过程中使用完全相同的旋转/裁剪指令重复处理完全相同的20幅图像。通常它可以工作,但大约有1/50倍会在图像中随机出现恐慌,尽管通常情况下图像上的恐慌较少(大部分为白色图像)

给出的恐慌是:

fatal error: unexpected signal during runtime execution
[signal 0xb code=0x2 addr=0x7fed87890340 pc=0x7fed91e2de3e]

runtime stack:
runtime: unexpected return pc for runtime.sigpanic called from 0x7fed91e2de3e
runtime.throw(0x88bcc5)
        /usr/local/go/src/pkg/runtime/panic.c:520 +0x69
runtime: unexpected return pc for runtime.sigpanic called from 0x7fed91e2de3e
runtime.sigpanic()
        /usr/local/go/src/pkg/runtime/os_linux.c:222 +0x3d

goroutine 16 [syscall]:
runtime.cgocall(0x401550, 0xc213ca98e8)
        /usr/local/go/src/pkg/runtime/cgocall.c:143 +0xe5 fp=0xc213ca98d0 sp=0xc213ca9888
private/leptonica._Cfunc_pixClipRectangle(0x7fed8788ff00, 0x7fed8788ffd0, 0x0, 0x8c2a28)
        private/leptonica/_obj/_cgo_defun.c:80 +0x31 fp=0xc213ca98e8 sp=0xc213ca98d0
private/leptonica.(*goPix).Crop(0xc20af90000, 0x900, 0x90, 0x4d8, 0x9a8, 0x4202c1, 0x0, 0x0)
        /home/go/src/private/leptonica/leptonica.go:154 +0xd8 fp=0xc213ca9960 sp=0xc213ca98e8
main.(*pageStruct).transformOriginal(0xc20805ae10, 0xc224772000, 0x69, 0x1)
        /home/root/go/frankenstein.go:1353 +0x30d fp=0xc213ca99c8 sp=0xc213ca9960
main.(*pageStruct).transformOriginalWithRecover(0xc20805ae10, 0xc224772000, 0x69, 0x1, 0x0, 0x5, 0x0, 0x0)
        /home/root/go/frankenstein.go:1403 +0xe1 fp=0xc213ca9a38 sp=0xc213ca99c8
main.(*book).processPages(0xc208a90000, 0x0, 0x0)
        /home/root/go/frankenstein.go:1542 +0x305 fp=0xc213ca9e48 sp=0xc213ca9a38
main.main()
        /home/root/go/frankenstein.go:1970 +0x3f5 fp=0xc213ca9f50 sp=0xc213ca9e48
runtime.main()
        /usr/local/go/src/pkg/runtime/proc.c:247 +0x11a fp=0xc213ca9fa8 sp=0xc213ca9f50
runtime.goexit()
        /usr/local/go/src/pkg/runtime/proc.c:1445 fp=0xc213ca9fb0 sp=0xc213ca9fa8
created by _rt0_go
        /usr/local/go/src/pkg/runtime/asm_amd64.s:97 +0x120

goroutine 19 [finalizer wait]:
runtime.park(0x424c70, 0x8a9c08, 0x88e8a9)
        /usr/local/go/src/pkg/runtime/proc.c:1369 +0x89
runtime.parkunlock(0x8a9c08, 0x88e8a9)
        /usr/local/go/src/pkg/runtime/proc.c:1385 +0x3b
runfinq()
        /usr/local/go/src/pkg/runtime/mgc0.c:2644 +0xcf
runtime.goexit()
        /usr/local/go/src/pkg/runtime/proc.c:1445

goroutine 33 [syscall, 7 minutes]:
runtime.goexit()
        /usr/local/go/src/pkg/runtime/proc.c:1445
我已尝试从中恢复,并使用名为transformOriginalWithRecover的函数重做transformOriginal函数。它实现延迟恢复,然后调用transformOriginal。不幸的是,这不起作用

我的恢复函数调用了通过C调用Leptonica的函数:

func (p *pageStruct) transformOriginalWithRecover(savefile string, detectOrientation bool, ontry, maxtries int) error {
    var err error = nil
    defer func() {
        if r := recover(); r != nil {
            ontry++
            if ontry >= maxtries {
                err = errors.New(`Failed to transform original.`)
            } else {
                if verbose {
                    fmt.Println(`Transform panicked. Recovered and retrying.`)
                }
                p.transformOriginalWithRecover(savefile, detectOrientation, ontry, maxtries)
            }
        }
    }()
    p.transformOriginal(savefile, detectOrientation)
    return err
}
我用
p.transformOriginalWithRecover(filename,true,0,5)
调用它,表明它应该在放弃之前尝试恢复5次

你知道我如何解决这个问题,或者如何从C引发的恐慌中恢复过来吗

更新

以下是导致此问题的特定功能。恐慌随机发生在
C.pixClipRectangle
内部。Leptonica剪辑图像的时间越长,这种情况发生的可能性就越大,这当然是有道理的,因为这给了GC更多的时间来决定激活

func (p *goPix) Crop(x, y, w, h int) (*goPix, error) {
    startX, startY, width, height := C.l_int32(x), C.l_int32(y), C.l_int32(w), C.l_int32(h)
    box := C.boxCreateValid(startX, startY, width, height)
    if box == nil {
        box = C.boxCreateValid(startX, startY, width, height)
        if box == nil {
            return p, errors.New(`Unable to create box.`)
        }
    }
    newpix := C.pixClipRectangle(p.cPix, box, nil)
    if newpix != p.cPix {
        p.Free()
    }
    C.boxDestroy(&box)
    C.free(unsafe.Pointer(box))
    if newpix == nil {
        return nil, errors.New(`Crop failed`)
    }
    pix := &goPix{
        cPix: newpix,
    }
    return pix, nil
}

你在程序上运行过竞赛条件检测器吗?没有,为什么会是竞赛条件?因为你说“有时是随机的”?好的。我将查找竞争条件并实现检测器。谢谢。另一种可能性是,如果您正在传递一个指向C的指针,该指针超出了范围,并且在cgo调用返回之前偶尔被GC’ed。