I have a Win64 Dll file, name "test.dll". Build it with MinGW64. Dll inside code like this:
// GOLANG CODE
package main
import "C"
import "time"
//export TestGo
func TestGo(str *C.char)*C.char {
gostr := C.GoString(str)
println("TestGo : ", str)
time.Sleep(time.Second * 3)
gostr = "return:" + gostr
cstr := C.CString(gostr)
return cstr
}
func main() {
}
And I have another Go program , try to import this "test.dll":
// GOLANG CODE
package main
import "C"
import (
"fmt"
"syscall"
"unsafe"
)
func main() {
pth := "./godll/test.dll"
dll := syscall.NewLazyDLL(pth)
ptrfun := dll.NewProc("TestGo")
msg := C.CString("this is a message")
res, _, _ := ptrfun.Call(uintptr(unsafe.Pointer(msg)))
gostr := C.GoString((*C.char)(unsafe.Pointer(res)))
fmt.Println(gostr)
for {
select {}
}
}
When I run this program, I got this:
TestGo : 0x1864b921f80
fatal error: unexpected signal during runtime execution
[signal 0xc0000005 code=0x1 addr=0x0 pc=0x6bf1f528]
goroutine 1 [running, locked to thread]:
runtime.throw(0x6bf524d9, 0x2a)
I:/Soft_Install/GO/src/runtime/panic.go:1116 +0x79 fp=0xc00010ef08 sp=0xc00010eed8 pc=0x6bef2859
runtime.sigpanic()
I:/Soft_Install/GO/src/runtime/signal_windows.go:240 +0x285 fp=0xc00010ef38 sp=0xc00010ef08 pc=0x6bf040a5
runtime.memmove(0x0, 0xc00004a050, 0x1)
I:/Soft_Install/GO/src/runtime/memmove_amd64.s:148 +0x108 fp=0xc00010ef40 sp=0xc00010ef38 pc=0x6bf1f528
runtime.heapBitsSetType(0xc00004a050, 0x50, 0x48, 0x6bf48a60)
I:/Soft_Install/GO/src/runtime/mbitmap.go:1373 +0x4cd fp=0xc00010f048 sp=0xc00010ef40 pc=0x6bed310d
runtime.mallocgc(0x50, 0x6bf48a60, 0x1, 0x6bf4c29e)
I:/Soft_Install/GO/src/runtime/malloc.go:1090 +0x5ee fp=0xc00010f0e8 sp=0xc00010f048 pc=0x6beccace
runtime.newobject(0x6bf48a60, 0x1)
I:/Soft_Install/GO/src/runtime/malloc.go:1195 +0x3f fp=0xc00010f118 sp=0xc00010f0e8 pc=0x6becd23f
time.Sleep(0xb2d05e00)
I:/Soft_Install/GO/src/runtime/time.go:182 +0x108 fp=0xc00010f158 sp=0xc00010f118 pc=0x6bf1b828
main.TestGo(0x1864b921f80, 0x0)
C:/Users/hgmmy/Desktop/GitGoCache/maquego/Test/GoDllTest/godll/dll.go:16 +0x93 fp=0xc00010f1d0 sp=0xc00010f158 pc=0x6bf2d833
main._cgoexpwrap_0fad9edfa800_TestGo(0x1864b921f80, 0x0)
_cgo_gotypes.go:73 +0x67 fp=0xc00010f208 sp=0xc00010f1d0 pc=0x6bf2d6a7
runtime.call32(0x0, 0x55e6dff3d0, 0x55e6dff540, 0x10)
I:/Soft_Install/GO/src/runtime/asm_amd64.s:540 +0x45 fp=0xc00010f238 sp=0xc00010f208 pc=0x6bf1cc25
runtime.cgocallbackg1(0x0)
I:/Soft_Install/GO/src/runtime/cgocall.go:332 +0x1b8 fp=0xc00010f2d0 sp=0xc00010f238 pc=0x6bec3558
runtime.cgocallbackg(0x0)
I:/Soft_Install/GO/src/runtime/cgocall.go:207 +0xe5 fp=0xc00010f338 sp=0xc00010f2d0 pc=0x6bec32e5
runtime: unexpected return pc for runtime.cgocallback_gofunc called from 0x78dca7
stack: frame={sp:0xc00010f338, fp:0xc00010f358} stack=[0xc000100000,0xc000110000)
000000c00010f238: 0000000000000000 00000055e6dff3d0
000000c00010f248: 00000055e6dff540 0000000000000010
000000c00010f258: 000000006befcd0f <runtime.exitsyscallfast+207> 000000c000020000
000000c00010f268: 0000000000000000 0000000000000000
000000c00010f278: 0202010000000000 0000000000000000
000000c00010f288: 0000000000000000 000000c00010f2c0
000000c00010f298: 000000c000034000 000000c00010f27d
000000c00010f2a8: 000000006bf539d0 0000000000000000
000000c00010f2b8: 0000000000000000 000000c00010f328
000000c00010f2c8: 000000006bec32e5 <runtime.cgocallbackg+229> 0000000000000000
000000c00010f2d8: 0000000000000000 0000000000724775
000000c00010f2e8: 000000006bf2d9a0 0000000000000001
000000c00010f2f8: 000000c00010f3e8 000000006bf2d9a0
000000c00010f308: 0000000000000000 0000000000000000
000000c00010f318: 000000c00010f360 000000c000034000
000000c00010f328: 00000055e6dff390 000000006bf1e3d2 <runtime.cgocallback_gofunc+178>
000000c00010f338: <0000000000000000 00000000008a0020
000000c00010f348: 000000c00010f360 !000000000078dca7
000000c00010f358: >00000000007247a9 000000000078f880
000000c00010f368: 00000000008a02e0 00000000008a0020
000000c00010f378: 000000c000034000 00000000008a0020
000000c00010f388: 000000c00010f3c8 000000000078ac1c
000000c00010f398: 000000000078f880 00000000008a02e0
000000c00010f3a8: 0000000000000000 0100000000000000
000000c00010f3b8: 00000000008a0020 0000000000832f90
000000c00010f3c8: 000000c00010fde8 000000000079e9fb
000000c00010f3d8: 000000006bf2d9a0 0000000000000001
000000c00010f3e8: 000001864b921f80 0000000000000000
000000c00010f3f8: 0000000000000000 0000000000000000
000000c00010f408: 0000000000000000 0000000000000000
000000c00010f418: 0000000000000000 0000000000000000
000000c00010f428: 0000000000000000 0000000000000000
000000c00010f438: 0000000000000000 0000000000000000
000000c00010f448: 0000000000000000 0000000000000000
runtime.cgocallback_gofunc(0x7247a9, 0x78f880, 0x8a02e0, 0x8a0020)
I:/Soft_Install/GO/src/runtime/asm_amd64.s:794 +0xb2 fp=0xc00010f358 sp=0xc00010f338 pc=0x6bf1e3d2
goroutine 1 [runnable, locked to thread]:
syscall.LoadDLL(0x6bf4d1ab, 0xc, 0x1c00004e078, 0x6bf6282d, 0x1c00004e000)
I:/Soft_Install/GO/src/syscall/dll_windows.go:92 +0x30d
syscall.(*LazyDLL).Load(0x1c000004060, 0x0, 0x0)
I:/Soft_Install/GO/src/syscall/dll_windows.go:245 +0xc8
syscall.(*LazyProc).Find(0x1c00004c2a0, 0x0, 0x0)
I:/Soft_Install/GO/src/syscall/dll_windows.go:300 +0xbf
syscall.(*LazyProc).mustFind(...)
I:/Soft_Install/GO/src/syscall/dll_windows.go:318
syscall.(*LazyProc).Addr(...)
I:/Soft_Install/GO/src/syscall/dll_windows.go:327
syscall.GetStdHandle(0xfffffffffffffff6, 0x1c00003bee8, 0x6bf280f8, 0x6bf461e0)
I:/Soft_Install/GO/src/syscall/zsyscall_windows.go:366 +0x3e
syscall.getStdHandle(0xfffffffffffffff6, 0x6bf4e818)
I:/Soft_Install/GO/src/syscall/syscall_windows.go:467 +0x32
syscall.init()
I:/Soft_Install/GO/src/syscall/syscall_windows.go:461 +0x129a
BUT!!!
I can call the dll with Python:
(Python Codes)
# PYTHON CODE
from ctypes import *
dll=CDLL("test.dll")
dll.TestGo.restype = c_char_p
msg=create_string_buffer("this is a message".encode())
res = dll.TestGo(msg)
print(string_at(res).decode())
Python return this:
TestGo : 0x259bd3aad90
return:this is a message
It return correct answer.
So, why I can't call this Dll functions from Go ......?
Related
I'm trying to debug memory issue on Go, i.e. RSS keeps on increasing, no leak is found via pprof, most likely is due to Go not returning memory to OS when it's freed (classic scavenger issue in Go: https://github.com/golang/go/issues/30333)
I'm trying to understand how the memory is allocated into heap and when they are deallocated.
strace doesn't help much so far, so I'm trying to use ltrace
ltrace -e malloc+free go run main.go
Unfortunately, it immediately crashes the program.
Any ideas how to use ltrace on go program? or it's not possible at all?
go->malloc(56) = 0x1f4f010
libpthread.so.0->free(nil) = <void>
go->free(0x1f4f010) = <void>
go->malloc(24) = 0x1f4f050
go->malloc(24) = 0x1f4f2c0
go->malloc(24) = 0x1f4f2c0
go->malloc(24) = 0x1f4f2c0
SIGILL: illegal instruction
PC=0x4aeb5e m=4 sigcode=2
goroutine 9 [syscall]:
syscall.Syscall6(0xf7, 0x1, 0x5865, 0xc000166dc8, 0x1000004, 0x0, 0x0, 0x4d0601, 0xc0003edf20, 0xc000166e08)
/usr/local/go/src/syscall/asm_linux_amd64.s:44 +0x5 fp=0xc000166d78 sp=0xc000166d70 pc=0x4aeb35
os.(*Process).blockUntilWaitable(0xc000027b30, 0x203000, 0xc0002d0000, 0x2)
/usr/local/go/src/os/wait_waitid.go:31 +0x98 fp=0xc000166e68 sp=0xc000166d78 pc=0x4d4db8
os.(*Process).wait(0xc000027b30, 0xa842a0, 0xa842a8, 0xa84298)
/usr/local/go/src/os/exec_unix.go:22 +0x39 fp=0xc000166ee0 sp=0xc000166e68 pc=0x4cca69
os.(*Process).Wait(...)
/usr/local/go/src/os/exec.go:125
os/exec.(*Cmd).Wait(0xc000325b80, 0x0, 0x0)
/usr/local/go/src/os/exec/exec.go:501 +0x60 fp=0xc000166f58 sp=0xc000166ee0 pc=0x50bbc0
os/exec.(*Cmd).Run(0xc000325b80, 0xc000260e10, 0x27)
/usr/local/go/src/os/exec/exec.go:341 +0x5c fp=0xc000166f80 sp=0xc000166f58 pc=0x50b05c
cmd/go/internal/work.(*Builder).toolID(0xc0000a55e0, 0xa3c61a, 0x7, 0xb, 0xc0001673c8)
/usr/local/go/src/cmd/go/internal/work/buildid.go:193 +0x44d fp=0xc000167170 sp=0xc000166f80 pc=0x83a51d
cmd/go/internal/work.(*Builder).buildActionID(0xc0000a55e0, 0xc0002e9400, 0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/cmd/go/internal/work/exec.go:242 +0x1215 fp=0xc000167588 sp=0xc000167170 pc=0x840c15
cmd/go/internal/work.(*Builder).build(0xc0000a55e0, 0xc0002e9400, 0x0, 0x0)
/usr/local/go/src/cmd/go/internal/work/exec.go:397 +0x52a6 fp=0xc000167e30 sp=0xc000167588 pc=0x847606
cmd/go/internal/work.(*Builder).Do.func2(0xc0002e9400)
/usr/local/go/src/cmd/go/internal/work/exec.go:117 +0x36d fp=0xc000167ef0 sp=0xc000167e30 pc=0x87666d
cmd/go/internal/work.(*Builder).Do.func3(0xc000028d60, 0xc0000a55e0, 0xc0003d9740)
/usr/local/go/src/cmd/go/internal/work/exec.go:177 +0x79 fp=0xc000167fc8 sp=0xc000167ef0 pc=0x876799
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1357 +0x1 fp=0xc000167fd0 sp=0xc000167fc8 pc=0x45c4c1
created by cmd/go/internal/work.(*Builder).Do
/usr/local/go/src/cmd/go/internal/work/exec.go:164 +0x3a1
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc000028d68)
/usr/local/go/src/runtime/sema.go:56 +0x42
sync.(*WaitGroup).Wait(0xc000028d60)
/usr/local/go/src/sync/waitgroup.go:130 +0x64
cmd/go/internal/work.(*Builder).Do(0xc0000a55e0, 0xc000152dc0)
/usr/local/go/src/cmd/go/internal/work/exec.go:186 +0x3c5
cmd/go/internal/run.runRun(0xea3d40, 0xc0000201a0, 0x1, 0x1)
/usr/local/go/src/cmd/go/internal/run/run.go:143 +0x54d
main.main()
/usr/local/go/src/cmd/go/main.go:189 +0x57f
goroutine 6 [syscall]:
os/signal.signal_recv(0x0)
/usr/local/go/src/runtime/sigqueue.go:147 +0x9c
os/signal.loop()
/usr/local/go/src/os/signal/signal_unix.go:23 +0x22
created by os/signal.init.0
/usr/local/go/src/os/signal/signal_unix.go:29 +0x41
goroutine 10 [runnable]:
os/exec.(*Cmd).Start.func1(0xc000325b80, 0xc0003d97e0)
/usr/local/go/src/os/exec/exec.go:434
created by os/exec.(*Cmd).Start
/usr/local/go/src/os/exec/exec.go:434 +0x608
goroutine 11 [runnable]:
os/exec.(*Cmd).Start.func1(0xc000325b80, 0xc0003d9820)
/usr/local/go/src/os/exec/exec.go:434
created by os/exec.(*Cmd).Start
/usr/local/go/src/os/exec/exec.go:434 +0x608
rax 0xf0013d48
rbx 0xc000030000
rcx 0xffffffffffffffff
rdx 0xc000166dc8
rdi 0x1
rsi 0x5865
rbp 0xc000166e58
rsp 0xc000166d70
r8 0x0
r9 0x0
r10 0x1000004
r11 0x202
r12 0xf1
r13 0x0
r14 0xb16d58
r15 0x0
rip 0x4aeb5e
rflags 0x10286
cs 0x33
fs 0x0
gs 0x0
+++ exited (status 2) +++
I wrote a custom dll export in c# which is working in c
This is my c# code for dll export
[DllExport]
/* GetMSLResult from the parameter as lat, lon, and gps elevation */
public static double GetMSLResult(IntPtr lat, IntPtr lon, IntPtr gpsElevation) => Helper.GetMSL(Helper.GetGeoID(Helper.IntPtrToDouble(lat), Helper.IntPtrToDouble(lon)), Helper.IntPtrToDouble(gpsElevation));
which is working and expose via
dumpbin /exports ClassLibrary1.dll
Which has my procedure is present
Also as i test in c code its working as well
this is my
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
typedef int(*GetMSLResult)(const wchar_t* str, const wchar_t* str1);
int main()
{
auto dll = ::LoadLibrary(L"ClassLibrary1.dll"); // さっき作ったC# DLLの名前を指定する
{
auto result = reinterpret_cast<GetMSLResult>(::GetProcAddress(dll, "Count"));
wcout << result(L"34.00", L"40.00") << endl; // this returns 74.00
wcout << result(L"90.00", L"40.00") << endl; // this returns 130.00
}
if ( dll )
::FreeLibrary(dll); // 解放は忘れずに!!
return 0;
}
this is working successfully, in golang i created a test code to read the exported dll not imported dll.
I wrote a simple test in windows how to do it but it seems i got an error and exited when i try to call the function i want to return the value
package main
import (
"fmt"
"syscall"
"unsafe"
)
func main() {
h := syscall.NewLazyDLL("ClassLibrary1.dll")
proc := h.NewProc("GetGeoID")
a := string("32.00")
n, _, _ := proc.Call(uintptr(unsafe.Pointer(&a)))
//fmt.Printf("teast %v", n)
fmt.Printf("Hello dll function returns %d\n", n)
}
Currently this is my golang code.
In my GeoID expected two parameter which is lattitude and longitude
so in my code in golang
a := string("32.00")
b := string("32.00")
i want this to pass the parameter a and b to my dll procedure functions
so that i could be able to get a result.
n, _, _ := proc.Call(uintptr(unsafe.Pointer(&a)))
But currently i received this error
Exception 0xe0434352 0x80131537 0x0 0x766afd62
PC=0x766afd62
syscall.Syscall(0x6e35290e, 0x1, 0x11006108, 0x0, 0x0, 0x0, 0x0, 0x0)
C:/Go/src/runtime/syscall_windows.go:184 +0xbb
syscall.(*Proc).Call(0x11004100, 0x110120e0, 0x1, 0x1, 0x10, 0x4907e0, 0x1, 0x110120e0)
C:/Go/src/syscall/dll_windows.go:171 +0x10a
syscall.(*LazyProc).Call(0x11049aa0, 0x110120e0, 0x1, 0x1, 0x0, 0x44bc01, 0x11034000, 0x11034000)
C:/Go/src/syscall/dll_windows.go:333 +0x48
main.main()
C:/Users/christopher/developer/go/src/gotest/main.go:16 +0x103
eax 0x19fbc0
ebx 0x5
ecx 0x5
edx 0x0
edi 0x1
esi 0x19fc80
ebp 0x19fc18
esp 0x19fbc0
eip 0x766afd62
eflags 0x216
cs 0x23
fs 0x53
gs 0x2b
exit status 2
Is there any good way i can call my custom dll procedure or function
like GetAge(34, 56) and the result in golang? currently ive been using LoadDLL, NewLazyDLL and other stuff but i could not be able to achieve my goal, does somebody can suggest a good way to do it?
My Go application connect to IBM MQ.
When my application throws segmentation violation error (signal SIGSEGV), signal handlers registered by IBM MQ make my application throw "non-Go code set up signal handler without SA_ONSTACK flag".
So how can I set that flag?
My code
package main
import (
"fmt"
"github.com/ibm-messaging/mq-golang/ibmmq"
)
type A struct {
Str string
}
type B struct {
Apointer *A
}
func main() {
connectIBMMQ()
b := B{}
fmt.Println(b.Apointer.Str)
}
const (
QMgrName = `QMgrName`
ChannelName = `ChannelName`
ConnectionName = `0.0.0.0(1416)`
Username = `username`
Password = `password`
)
func connectIBMMQ() {
mqcd := ibmmq.NewMQCD()
mqcd.ChannelName = ChannelName
mqcd.ConnectionName = ConnectionName
csp := ibmmq.NewMQCSP()
csp.AuthenticationType = ibmmq.MQCSP_AUTH_USER_ID_AND_PWD
csp.UserId = Username
csp.Password = Password
cno := ibmmq.NewMQCNO()
cno.ClientConn = mqcd
cno.Options = ibmmq.MQCNO_CLIENT_BINDING + ibmmq.MQCNO_RECONNECT + ibmmq.MQCNO_HANDLE_SHARE_BLOCK
cno.SecurityParms = csp
ibmmq.Connx(QMgrName, cno)
}
Ref
https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.dev.doc/q025880_.htm
https://golang.org/pkg/os/signal/#hdr-Go_programs_that_use_cgo_or_SWIG
Full error
signal 11 received but handler not on signal stack
fatal error: non-Go code set up signal handler without SA_ONSTACK flag
runtime stack:
runtime: unexpected return pc for runtime.sigtramp called from 0x7f60f6e9a517
stack: frame={sp:0xc000046628, fp:0xc000046680} stack=[0xc00003e578,0xc000046978)
000000c000046528: 000000c000046530 00000000004549a0 <runtime.throw.func1+0>
000000c000046538: 00000000004e2c3b 0000000000000039
000000c000046548: 000000c000046568 00000000004415df <runtime.sigNotOnStack+127>
000000c000046558: 00000000004e2c3b 0000000000000039
000000c000046568: 000000c000046618 0000000000440c6d <runtime.sigtrampgo+749>
000000c000046578: 000000000000000b 000000c000046600
000000c000046588: 000000c000046880 0000000000000000
000000c000046598: 0000000000000000 000000c000046628
000000c0000465a8: 0000000000000000 0000000000000000
000000c0000465b8: 0000000000000000 0000000000000000
000000c0000465c8: 0000000000000000 000000c000000180
000000c0000465d8: 0000000000000000 ffffffffffffffff
000000c0000465e8: 0000000000000000 0000000000000000
000000c0000465f8: 0000000000000000 000000c000002000
000000c000046608: 0000000000000000 0000000000008000
000000c000046618: 000000c000046670 0000000000459a33 <runtime.sigtramp+67>
000000c000046628: <000000000000000b 000000c0000469b0
000000c000046638: 000000c000046880 000000c000046880
000000c000046648: 000000c0000469b0 0000000000000000
000000c000046658: 000000000000000b 000000c000046670
000000c000046668: 00007f60f78213c0 000000000262e400
000000c000046678: !00007f60f6e9a517 >000000c000046690
000000c000046688: 8e26f8f48c919100 0000000000000000
000000c000046698: 0000000000000000 0000000000000008
000000c0000466a8: 0000000000000000 000000c000000180
000000c0000466b8: 0000000000000000 0000000000000000
000000c0000466c8: 0000000000000000 0000000000000000
000000c0000466d8: 0000000000000000 0000000000000000
000000c0000466e8: 0000000000000000 0000000000000000
000000c0000466f8: 0000000000000000 0000000000000000
000000c000046708: 0000000000000000 0000000000000000
000000c000046718: 0000000000000000 000000c000046f88
000000c000046728: 0000000000000004 0000000000000012
000000c000046738: 00000000004f21e1 0000000000000000
000000c000046748: 00007f60f6e9b45a 0000000000000000
000000c000046758: 0000000000000000 0000000000000000
000000c000046768: 0000000000000000 0000000000000000
000000c000046778: 0000000000000000
runtime.throw(0x4e2c3b, 0x39)
/usr/local/go/src/runtime/panic.go:617 +0x72
runtime.sigNotOnStack(0xb)
/usr/local/go/src/runtime/signal_unix.go:576 +0x7f
runtime.sigtrampgo(0xb, 0xc0000469b0, 0xc000046880)
/usr/local/go/src/runtime/signal_unix.go:334 +0x2ed
runtime: unexpected return pc for runtime.sigtramp called from 0x7f60f6e9a517
stack: frame={sp:0xc000046628, fp:0xc000046680} stack=[0xc00003e578,0xc000046978)
000000c000046528: 000000c000046530 00000000004549a0 <runtime.throw.func1+0>
000000c000046538: 00000000004e2c3b 0000000000000039
000000c000046548: 000000c000046568 00000000004415df <runtime.sigNotOnStack+127>
000000c000046558: 00000000004e2c3b 0000000000000039
000000c000046568: 000000c000046618 0000000000440c6d <runtime.sigtrampgo+749>
000000c000046578: 000000000000000b 000000c000046600
000000c000046588: 000000c000046880 0000000000000000
000000c000046598: 0000000000000000 000000c000046628
000000c0000465a8: 0000000000000000 0000000000000000
000000c0000465b8: 0000000000000000 0000000000000000
000000c0000465c8: 0000000000000000 000000c000000180
000000c0000465d8: 0000000000000000 ffffffffffffffff
000000c0000465e8: 0000000000000000 0000000000000000
000000c0000465f8: 0000000000000000 000000c000002000
000000c000046608: 0000000000000000 0000000000008000
000000c000046618: 000000c000046670 0000000000459a33 <runtime.sigtramp+67>
000000c000046628: <000000000000000b 000000c0000469b0
000000c000046638: 000000c000046880 000000c000046880
000000c000046648: 000000c0000469b0 0000000000000000
000000c000046658: 000000000000000b 000000c000046670
000000c000046668: 00007f60f78213c0 000000000262e400
000000c000046678: !00007f60f6e9a517 >000000c000046690
000000c000046688: 8e26f8f48c919100 0000000000000000
000000c000046698: 0000000000000000 0000000000000008
000000c0000466a8: 0000000000000000 000000c000000180
000000c0000466b8: 0000000000000000 0000000000000000
000000c0000466c8: 0000000000000000 0000000000000000
000000c0000466d8: 0000000000000000 0000000000000000
000000c0000466e8: 0000000000000000 0000000000000000
000000c0000466f8: 0000000000000000 0000000000000000
000000c000046708: 0000000000000000 0000000000000000
000000c000046718: 0000000000000000 000000c000046f88
000000c000046728: 0000000000000004 0000000000000012
000000c000046738: 00000000004f21e1 0000000000000000
000000c000046748: 00007f60f6e9b45a 0000000000000000
000000c000046758: 0000000000000000 0000000000000000
000000c000046768: 0000000000000000 0000000000000000
000000c000046778: 0000000000000000
runtime.sigtramp(0xc000046690, 0x8e26f8f48c919100, 0x0, 0x0, 0x8, 0x0, 0xc000000180, 0x0, 0x0, 0x0, ...)
/usr/local/go/src/runtime/sys_linux_amd64.s:357 +0x43
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004afe8 sp=0xc00004afe0 pc=0x457e41
goroutine 1 [running]:
goroutine running on other thread; stack unavailable
You can try setting the environment variable "MQS_NO_SYNC_SIGNAL_HANDLING=true" to disable some of MQ's signal setting. That should at least give a better idea of where the SEGV is coming from.
This is the first time I have had to make calls to native libraries from Go.
I am trying to setup event hooks with the windows libraries to listen for network interface changes, so far I have been successful with setting up a listener with NotifyAddrChange.
Now I am trying with NotifyIpInterfaceChange with the following code
package main
import (
"golang.org/x/sys/windows"
"log"
"syscall"
"unsafe"
)
var (
modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll")
procNotifyIpInterfaceChange = modiphlpapi.NewProc("NotifyIpInterfaceChange")
)
type context struct{}
func main() {
log.Printf("Loaded [iphlpapi.dll] at {%#v}", modiphlpapi.Handle())
log.Printf("Found [NotifyIpInterfaceChange] at {%#v}", procNotifyIpInterfaceChange.Addr())
context := &context{}
interfaceChange := windows.Handle(0)
ret, _, errNum := procNotifyIpInterfaceChange.Call(syscall.AF_UNSPEC, syscall.NewCallback(callback), uintptr(unsafe.Pointer(context)), 0, uintptr(interfaceChange))
log.Printf("%#v %#v", ret, errNum)
}
func callback(callerContext, row, notificationType uintptr) uintptr {
log.Printf("callback invoked by Windows API (%#v %#v %#v)", callerContext, row, notificationType)
return 0
}
The code compiles fine and starts up without any issue, the problem happens once the function is invoke, then I get the following exception
D:\>event-listen_type2.exe
2017/06/22 22:12:39 Loaded [iphlpapi.dll] at {0x7ffac96f0000}
2017/06/22 22:12:39 Found [NotifyIpInterfaceChange] at {0x7ffac96f7e20}
Exception 0xc0000005 0x1 0x0 0x7ffac96f7edb
PC=0x7ffac96f7edb
syscall.Syscall6(0x7ffac96f7e20, 0x5, 0x0, 0x454170, 0x54d360, 0x0, 0x0, 0x0, 0xc042015350, 0xc042015300, ...)
/usr/local/Cellar/go/1.8.3/libexec/src/runtime/syscall_windows.go:174 +0x6b
github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows.(*Proc).Call(0xc04203a620, 0xc042050300, 0x5, 0x5, 0x30, 0x4b12e0, 0x1, 0xc042050300)
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows/dll_windows.go:139 +0x5c1
github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows.(*LazyProc).Call(0xc042050270, 0xc042050300, 0x5, 0x5, 0x1, 0xc04201a000, 0xc04202df78, 0x4043a3)
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/vendor/golang.org/x/sys/windows/dll_windows.go:309 +0x66
main.main()
/Users/liam/git/go_path/src/github.com/LiamHaworth/windows-network-events/main_windows.go:25 +0x229
rax 0x0
rbx 0xc3f10
rcx 0x1fb5cd87abfd0000
rdi 0x0
rsi 0x454170
rbp 0xc04202dc00
rsp 0x8fdf0
r8 0x8fb78
r9 0x7ffac96fb4c0
r10 0x0
r11 0x8fcf0
r12 0x0
r13 0xffffffee
r14 0x0
r15 0xaa
rip 0x7ffac96f7edb
rflags 0x10246
cs 0x33
fs 0x53
gs 0x2b
From some googling I know that exception type 0xc0000005 is a access violation thrown by the CPU when a program tries to access memory not allocated to it but looking through my code I can't tell where that is happening. All pointers passed are for items in the application.
Any help here would be magnificent.
According to documentation, the latest parameter of NotifyIpInterfaceChange is both in/out and need to be a pointer to HANDLE. Change the system call to:
ret, _, errNum := procNotifyIpInterfaceChange.Call(syscall.AF_UNSPEC,
syscall.NewCallback(callback),
uintptr(unsafe.Pointer(context)),
0,
uintptr(unsafe.Pointer(&interfaceChange))) //this must be pointer
EDIT:
As mentioned in the comment and this go-nuts discussion, for multi-threaded callback, import "C" need to be added, even if we don't use cgo.
I ran ltrace on a Word processor and opened a sample file, but surprisingly got only two calls.
__libc_start_main(0x8048820, 1, 0xbfe08844, 0x8048850, 0x80488b0 <unfinished ...>
_ZN10AP_UnixApp4mainEPKciPPc(0x8048910, 1, 0xbfe08844, 0xb61feff4, 0x8048850) = 0
+++ exited (status 0) +++
Shouldn't ltrace print all library calls?
The problem is that ltrace only intercepts calls from the main executable (abiword here) to other shared libraries, but does not intercept calls from one shared library to another.
For abiword, the main function doesn't actually do much:
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400a70 <+0>: mov %rsi,%rdx
0x0000000000400a73 <+3>: mov %edi,%esi
0x0000000000400a75 <+5>: mov $0x400b6c,%edi
0x0000000000400a7a <+10>: jmpq 0x400950 <_ZN10AP_UnixApp4mainEPKciPPc#plt>
End of assembler dump.
As you can see, it simply does a return AP_UnixApp::main(argc, "abiword", argv);, and all the real activity happens in the library that implements AP_UnixApp::main (in my case, in /usr/lib/libabiword-2.8.so).
On a Fedora system, you can try using frysk instead. In particular, this:
ftrace -sym '*' abiword
produces a (very long) trace, beginning with:
528.528 attached /usr/bin/abiword
528.528 call #libpthread.so.0#_init(0x1, 0x7fffa8ba5bd8, 0x7fffa8ba5be8, 0x7fffa8ba5be8, 0x1f25bc2, 0x7)
528.528 call #libpthread.so.0#__pthread_initialize_minimal(0x1, 0x7fffa8ba5bd8, 0x7fffa8ba5be8, 0x7fffa8ba5be8, 0x1f25bc2, 0x7)
528.528 call #libpthread.so.0#__libc_sigaction(0x20, 0x7fffa8ba5a70, 0x0, 0x0, 0x1f25bc2, 0x7)
528.528 call #libpthread.so.0#__libc_sigaction(0x21, 0x7fffa8ba5a70, 0x0, 0x7f32501f27b0, 0x0, 0x7)
528.528 call #libc.so.6#getrlimit(0x3, 0x7fffa8ba5b10, 0x3f, 0x40, 0x0, 0x7) = 0
528.528 call #libc.so.6#sysconf(0x1e, 0x7fffa8ba5b10, 0x3f, 0x30220e7b17, 0x0, 0x7)
528.528 call #libc.so.6#getpagesize(0x1e, 0x7fffa8ba5b10, 0xfffffffffff51435, 0x30220e7b17, 0x0, 0x7) = 4096
528.528 leave #libc.so.6#sysconf = 4096
528.528 call #libc.so.6#__libc_dl_error_tsd(0x1e, 0x7fffa8ba5b10, 0x800000, 0x2a40, 0x0, 0x7) = 139854069229848
...
Ftrace documentation here.