Go Exception "signal arrived during cgo execution"

huangapple go评论62阅读模式
英文:

Go Exception "signal arrived during cgo execution"

问题

在调用dll时,Go会在什么情况下出现类似"在cgo执行期间收到信号"的panic?

要调用的代码是基于Go发行版中src目录下的zsyscall_windows.go中的示例:

var (
    // 使用dumpbin /exports找到的入口名称
    dllSweph = syscall.NewLazyDLL("swedll32.dll")

    _swe_jdut1_to_utc = dllSweph.NewProc("_swe_jdut1_to_utc@36")
    _swe_julday       = dllSweph.NewProc("_swe_julday@24")
)

func swe_julday(year, month, day int32, hour float64, gregflag int32) float64 {
    r, _, errn := syscall.Syscall6(
        _swe_julday.Addr(),
        5,
        uintptr(year),
        uintptr(month),
        uintptr(day),
        uintptr(hour),
        uintptr(gregflag),
        0)

    if r == 0 {
        if errn != 0 {
            panic(error(errn))
        }
    }

    return float64(r)
}

func swe_jdut1_to_utc(tjd_ut float64, gregflag int32, iyear, imonth, iday, ihour, imin *int32, dsec *float64) {
    defer func() {
        if e := recover(); e != nil {
        }
    }()

    syscall.Syscall9(
        _swe_jdut1_to_utc.Addr(),
        8,
        uintptr(tjd_ut),
        uintptr(gregflag),
        uintptr(unsafe.Pointer(iyear)),
        uintptr(unsafe.Pointer(imonth)),
        uintptr(unsafe.Pointer(iday)),
        uintptr(unsafe.Pointer(ihour)),
        uintptr(unsafe.Pointer(imin)),
        uintptr(unsafe.Pointer(dsec)),
        0)
}

现在当我调用swe_julday时,一切似乎都很正常,尽管实际上并不是这样,它给出了一个错误的答案。而当调用swe_jdut1_to_utc时,我得到了以下错误:

Exception 0xc0000005 0x1 0x42e5e5 0x3235ce40
PC=0x3235ce40
signal arrived during cgo execution

.../sweph.swe_jdut1_to_utc(0x40000000, 0x4150b979, 0x1, 0x1207bf24, 0x1207bf28, 0x1207bf34, 0x1207bf30, 0x1207bf2c, 0x1207bf38)
...(trace info)

eax     0x0
ebx     0x1207be94
ecx     0x1207bf38
edx     0x42e5e5
edi     0xcfeac
esi     0x0
ebp     0xcfe5c
esp     0xcfdd8
eip     0x3235ce40
eflags  0x10246
cs      0x23
fs      0x53
gs      0x2b
exit status 2

exit status 1

环境:

  • Windows 8 x64
  • Go 1.4 x86
  • GCC x86

我不知道是否真的需要gcc来调用一个dll,但我已经安装了它,因为错误是关于cgo的。所有命令都在路径中。使用管理员权限编译时出现相同的错误。

被调用的C函数是:

void swe_jdut1_to_utc (double tjd_ut, int32 gregflag, int32 *iyear, int32 *imonth, int32 *iday, int32 *ihour, int32 *imin, double *dsec)

而在该dll中导入并调用此函数的C#函数是:

[DllImport("swedll32.dll", EntryPoint = "swe_jdut1_to_utc")]
public static extern void swe_jdut1_to_utc(
    double tjd_ut,
    int gregflag,
    ref Int32 iyear, ref Int32 imonth, ref Int32 iday,
    ref Int32 ihour, ref Int32 imin, ref double dsec);
英文:

In what circumstances Go panics like "signal arrived during cgo execution" when calling a dll?

The code to be called is - based on samples in zsyscall_windows.go in src of go distribution:

var (
    // entry names found using dumpbin /exports
	dllSweph = syscall.NewLazyDLL("swedll32.dll")

    _swe_jdut1_to_utc = dllSweph.NewProc("_swe_jdut1_to_utc@36")
    _swe_julday       = dllSweph.NewProc("_swe_julday@24")
)

func swe_julday(year, month, day int32, hour float64, gregflag int32) float64 {
	r, _, errn := syscall.Syscall6(
		_swe_julday.Addr(),
		5,
		uintptr(year),
		uintptr(month),
		uintptr(day),
		uintptr(hour),
		uintptr(gregflag),
		0)

	if r == 0 {
		if errn != 0 {
			panic(error(errn))
		}
	}

	return float64(r)
}

func swe_jdut1_to_utc(tjd_ut float64, gregflag int32, iyear, imonth, iday, ihour, imin *int32, dsec *float64) {
	defer func() {
		if e := recover(); e != nil {
		}
	}()

	syscall.Syscall9(
		_swe_jdut1_to_utc.Addr(),
		8,
		uintptr(tjd_ut),
		uintptr(gregflag),
		uintptr(unsafe.Pointer(iyear)),
		uintptr(unsafe.Pointer(imonth)),
		uintptr(unsafe.Pointer(iday)),
		uintptr(unsafe.Pointer(ihour)),
		uintptr(unsafe.Pointer(imin)),
		uintptr(unsafe.Pointer(dsec)),
		0)
}

Now when I call swe_julday everything seems to be fine; although it's not and it gives a wrong answer. And when swe_jdut1_to_utc is called, I get:

Exception 0xc0000005 0x1 0x42e5e5 0x3235ce40
PC=0x3235ce40
signal arrived during cgo execution

.../sweph.swe_jdut1_to_utc(0x40000000, 0x4150b979, 0x1, 0x1207bf24, 0x1207bf28, 0x1207bf34, 0x1207bf30, 0x1207bf2c, 0x1207bf38)
...(trace info)

eax     0x0
ebx     0x1207be94
ecx     0x1207bf38
edx     0x42e5e5
edi     0xcfeac
esi     0x0
ebp     0xcfe5c
esp     0xcfdd8
eip     0x3235ce40
eflags  0x10246
cs      0x23
fs      0x53
gs      0x2b
exit status 2

exit status 1

Environment:

Windows 8 x64
go 1.4    x86
gcc       x86

And I do not know if gcc is really needed to just call a dll, but I've installed it any way because the error was about cgo. All commands are in the path. Same error when compiling with administrative privileges.

The C function that is being called is:

void swe_jdut1_to_utc (double tjd_ut, int32 gregflag, int32 *iyear, int32 *imonth, int32 *iday, int32 *ihour, int32 *imin, double *dsec)

And the C# function which imports and calls this function in that dll (& works) is:

[DllImport("swedll32.dll", EntryPoint = "swe_jdut1_to_utc")]
public static extern void swe_jdut1_to_utc(
    double tjd_ut,
    int gregflag,
    ref Int32 iyear, ref Int32 imonth, ref Int32 iday,
    ref Int32 ihour, ref Int32 imin, ref double dsec);

答案1

得分: 1

我成功构建了一个使用swe_julday函数的Delphi应用程序。不幸的是,我发现它使用fstp汇编指令来获取swe_julday返回的结果。Go的syscall.Syscall不支持这个功能。很抱歉,你运气不好。我认为你最好的选择是如果可能的话,使用CGO来使用mingw编译器构建你的库。抱歉。

英文:

I managed to build delphi app that uses swe_julday function. Unfortunately I can see it uses fstp asm instruction to retrieve result returned by swe_julday. Go's syscall.Syscall does not support this functionality. You are our of luck. I think your best bet is to use CGO if it is possible to build your library with mingw compiler. Sorry

Alex

huangapple
  • 本文由 发表于 2014年12月29日 06:10:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/27681094.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定