###質問内容
現在Go言語でプログラミングを勉強中で、cgoでDLLの関数を呼び出すようなプログラムを作っています。
呼び出したいライブラリproprietarydll.dllは下記のproprietarydll.hにあるような関数を持っており、
こちらをGo言語から呼びだそうとしていました。
ところが、proprietarydll.dllの関数を呼び出した後しばらくすると、
**"fatal error: invalid stack pointer"**というエラーが出てプログラムが終了してしまいました。
エラーはGCの際に起きているようだったので、
proprietarydll.dllの関数呼び出しの後にGCを呼び出すcrash.goのようなプログラムを書いたところ、
GCが行われた時に同様のエラーが発生していることが確認できました。
しかし、エラーが発生している箇所はわかったのですが、
このエラーが何故起きているのかはわかりませんでした。
類似した質問もなく、修正のための原因がわからず、質問しました。
このエラーの原因は何でしょうか。
(※なお、DLLは頂いたもので、中で何をやっているのかは分かりません。
もともとはC/C++から使っていたライブラリであったようです。)
###発生している問題・エラーメッセージ
複数回funcCを呼び出すプログラムの吐くエラーから、
GCの前後でエラーが起きている様子である、というところまではわかりました。
したがって、下記のようにCの関数呼び出しの前後にruntime.GC()を呼び出すと、
同様のエラー**"fatal error: invalid stack pointer"**を出してプログラムが落ちました。
エラーメッセージは次のとおりです。
before: GC(funcB) 0xe630020 after: GC(funcB) 0xe630020 before: GC(funcC) 0x1a0 runtime: bad pointer in frame main.main at 0x222cdf0c: 0x1a0 fatal error: invalid stack pointer runtime stack: runtime.throw(0x4eeb10, 0x15) C:/Go/src/runtime/panic.go:547 +0x7f fp=0x2a2fa0c sp=0x2a2fa00 runtime.adjustpointers(0x222cdf0c, 0x2a2facc, 0x2a2fcac, 0x50e784) C:/Go/src/runtime/stack.go:579 +0x235 fp=0x2a2fa80 sp=0x2a2fa0c runtime.adjustframe(0x2a2fc3c, 0x2a2fcac, 0x2a2fb01) C:/Go/src/runtime/stack.go:644 +0x163 fp=0x2a2fae8 sp=0x2a2fa80 runtime.gentraceback(0x44aa80, 0x222cdcf8, 0x0, 0x222b8000, 0x0, 0x0, 0x7fffffff, 0x506e60, 0x2a2fcac, 0x0, ...) C:/Go/src/runtime/traceback.go:369 +0xbce fp=0x2a2fc68 sp=0x2a2fae8 runtime.copystack(0x222b8000, 0x1000) C:/Go/src/runtime/stack.go:759 +0x161 fp=0x2a2fda0 sp=0x2a2fc68 runtime.shrinkstack(0x222b8000) C:/Go/src/runtime/stack.go:1026 +0x122 fp=0x2a2fdb8 sp=0x2a2fda0 runtime.markroot(0x5) C:/Go/src/runtime/mgcmark.go:155 +0x23e fp=0x2a2fe0c sp=0x2a2fdb8 runtime.gcDrain(0x2a2fe44, 0x0) C:/Go/src/runtime/mgcmark.go:812 +0x26a fp=0x2a2fe34 sp=0x2a2fe0c runtime.gchelper() C:/Go/src/runtime/mgc.go:1806 +0x87 fp=0x2a2fe64 sp=0x2a2fe34 runtime.stopm() C:/Go/src/runtime/proc.go:1541 +0x10c fp=0x2a2fe74 sp=0x2a2fe64 runtime.findrunnable(0x222b4a00, 0x0) C:/Go/src/runtime/proc.go:1976 +0x62a fp=0x2a2febc sp=0x2a2fe74 runtime.schedule() C:/Go/src/runtime/proc.go:2075 +0x202 fp=0x2a2fedc sp=0x2a2febc runtime.park_m(0x222b84e0) C:/Go/src/runtime/proc.go:2140 +0x163 fp=0x2a2fef0 sp=0x2a2fedc runtime.mcall(0x933658) C:/Go/src/runtime/asm_386.s:255 +0x47 fp=0x2a2fef8 sp=0x2a2fef0 goroutine 1 [copystack]: runtime.systemstack_switch() C:/Go/src/runtime/asm_386.s:267 fp=0x222cdcfc sp=0x222cdcf8 runtime.gcMarkTermination() C:/Go/src/runtime/mgc.go:1182 +0x121 fp=0x222cdec4 sp=0x222cdcfc runtime.gcStart(0x2, 0x222c2000) C:/Go/src/runtime/mgc.go:1018 +0x3f4 fp=0x222cdee4 sp=0x222cdec4 runtime.GC() C:/Go/src/runtime/mgc.go:840 +0x26 fp=0x222cdef0 sp=0x222cdee4 main.main() C:/dev/crash/crash.go:40 +0x3b4 fp=0x222cdfa8 sp=0x222cdef0 runtime.main() C:/Go/src/runtime/proc.go:188 +0x234 fp=0x222cdfd0 sp=0x222cdfa8 runtime.goexit() C:/Go/src/runtime/asm_386.s:1585 +0x1 fp=0x222cdfd4 sp=0x222cdfd0 goroutine 17 [syscall, locked to thread]: runtime.goexit() C:/Go/src/runtime/asm_386.s:1585 +0x1 fp=0x222cbfd4 sp=0x222cbfd0 goroutine 2 [force gc (idle)]: runtime.gopark(0x506f84, 0x55b488, 0x4e7b40, 0xf, 0x14, 0x1) C:/Go/src/runtime/proc.go:262 +0x130 fp=0x222befa4 sp=0x222bef90 runtime.goparkunlock(0x55b488, 0x4e7b40, 0xf, 0x222b8014, 0x1) C:/Go/src/runtime/proc.go:268 +0x4b fp=0x222befc0 sp=0x222befa4 runtime.forcegchelper() C:/Go/src/runtime/proc.go:229 +0xaa fp=0x222befd8 sp=0x222befc0 runtime.goexit() C:/Go/src/runtime/asm_386.s:1585 +0x1 fp=0x222befdc sp=0x222befd8 created by runtime.init.4 C:/Go/src/runtime/proc.go:218 +0x2a goroutine 3 [GC sweep wait]: runtime.gopark(0x506f84, 0x55b500, 0x4e70b0, 0xd, 0x41c914, 0x1) C:/Go/src/runtime/proc.go:262 +0x130 fp=0x222bff98 sp=0x222bff84 runtime.goparkunlock(0x55b500, 0x4e70b0, 0xd, 0x14, 0x1) C:/Go/src/runtime/proc.go:268 +0x4b fp=0x222bffb4 sp=0x222bff98 runtime.bgsweep(0x222aa0c0) C:/Go/src/runtime/mgcsweep.go:63 +0xa0 fp=0x222bffd0 sp=0x222bffb4 runtime.goexit() C:/Go/src/runtime/asm_386.s:1585 +0x1 fp=0x222bffd4 sp=0x222bffd0 created by runtime.gcenable C:/Go/src/runtime/mgc.go:191 +0x52 goroutine 4 [finalizer wait]: runtime.gopark(0x506f84, 0x56b1e8, 0x4e7aa0, 0xe, 0x14, 0x1) C:/Go/src/runtime/proc.go:262 +0x130 fp=0x222c0f84 sp=0x222c0f70 runtime.goparkunlock(0x56b1e8, 0x4e7aa0, 0xe, 0x14, 0x1) C:/Go/src/runtime/proc.go:268 +0x4b fp=0x222c0fa0 sp=0x222c0f84 runtime.runfinq() C:/Go/src/runtime/mfinal.go:158 +0x9e fp=0x222c0fd8 sp=0x222c0fa0 runtime.goexit() C:/Go/src/runtime/asm_386.s:1585 +0x1 fp=0x222c0fdc sp=0x222c0fd8 created by runtime.createfing C:/Go/src/runtime/mfinal.go:139 +0x5c
###該当のソースコード
proprietarydll.h
C
1#include <winsock2.h> 2#include <windows.h> 3 4// dummy value 5#define SUCCESS 12345 6 7// funcA is called to initialize this dll. 8DWORD funcA(); 9 10// funcB returns a handle for funcC 11HANDLE funcB(); 12 13// funcC requires a handle returned by funcB 14HANDLE funcC(HANDLE);
crash.go
go
1package main 2 3import ( 4 "fmt" 5 "log" 6 "runtime" 7) 8 9/* 10#cgo LDFLAGS: -L. -lproprietarydll 11#cgo CFLAGS: -I . 12#include "proprietarydll.h" 13*/ 14import "C" 15 16func main() { 17 if status, err := C.funcA(); status != C.SUCCESS || err != nil { 18 log.Fatal(err) 19 } 20 21 handleB, err := C.funcB() 22 if handleB == nil || err != nil { 23 if err != nil { 24 log.Fatal(err) 25 } 26 log.Fatal("handleB is nil") 27 } 28 fmt.Println("before:\tGC(funcB)", handleB) 29 runtime.GC() // <- ここはエラーが出ない 30 fmt.Println("after:\tGC(funcB)", handleB) 31 32 handleC, err := C.funcC(handleB) 33 if handleC == nil || err != nil { 34 if err != nil { 35 log.Fatal("handleC is nil") 36 } 37 return 38 } 39 fmt.Println("before:\tGC(funcC)", handleC) 40 runtime.GC() // <- ここはエラーが出る 41 fmt.Println("after:\tGC(funcC)", handleC) 42}
###補足情報(言語/FW/ツール等のバージョンなど)
OS: Windows 7 64bit
言語: Go 1.6.2 32bit
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。