我正在嘗試在Go 中使用回呼 實作MiniDumpWriteDump。
呼叫MiniDumpWriteDump:
callback := syscall.NewCallback(miniDumpCallback) var newCallbackRoutine MINIDUMP_CALLBACK_INFORMATION newCallbackRoutine.CallbackParam = 0 newCallbackRoutine.CallbackRoutine = callback ret, _, err := miniDumpWriteDump.Call( uintptr(processHandle), uintptr(processId), uintptr(dumpFile), uintptr(options), 0, 0, uintptr(unsafe.Pointer(&newCallbackRoutine)), )
回呼函數本身:
func miniDumpCallback(_ uintptr, CallbackInput *MINIDUMP_CALLBACK_INPUT, _ uintptr) uintptr { fmt.Println(CallbackInput.ProcessId, CallbackInput.CallbackType) return 1 }
類型定義:
type MINIDUMP_CALLBACK_INPUT struct { ProcessId win32.ULONG ProcessHandle win32.HANDLE CallbackType win32.ULONG CallbackInfo uintptr } type MINIDUMP_CALLBACK_INFORMATION struct { CallbackRoutine uintptr CallbackParam uintptr }
回呼被調用,一些字段收到正確的數據,但一些字段得到無意義值。
例如,上面的回調正確接收CallbackInput 的ProcessId 字段,但在應該接收時接收隨機整數作為CallbackType MINIDUMP_CALLBACK_TYPE枚舉。
輸出:
12544 0 12544 1133445120 12544 12548 12544 13028 12544 1114112 12544 1023344640 12544 999620608 12544 990117888 12544 992542720 12544 1005518848 12544 1994850304 12544 1114112 12544 1994915840
正如評論所建議的,問題出在結構對齊。
如@IInspectable 所解釋的,導出MiniDumpWriteDump 函數和MINIDUMP_CALLBACK_INPUT 結構的minidumpapiset.h 對32 位元 和64 位元都使用4 位元組 對齊方式 strong> 架構,而Go 預設為64 位元使用8 位元組 對齊方式,並且不提供自動更改它的方法。
解決方案是手動讀取結構體。這是一個工作範例:
type MINIDUMP_CALLBACK_INPUT struct { ProcessId uint32 ProcessHandle uintptr CallbackType uint32 CallbackInfo uintptr} func ptrToMinidumpCallbackInput(ptrCallbackInput uintptr) MINIDUMP_CALLBACK_INPUT{ var input MINIDUMP_CALLBACK_INPUT input.ProcessId = *(*uint32)(unsafe.Pointer(ptrCallbackInput)) input.ProcessHandle = *(*uintptr)(unsafe.Pointer(ptrCallbackInput + unsafe.Sizeof(uint32(0)))) input.CallbackType = *(*uint32)(unsafe.Pointer(ptrCallbackInput + unsafe.Sizeof(uint32(0)) + unsafe.Sizeof(uintptr(0)))) input.CallbackInfo = *(*uintptr)(unsafe.Pointer(ptrCallbackInput + unsafe.Sizeof(uint32(0)) + unsafe.Sizeof(uintptr(0)) + unsafe.Sizeof(uint32(0)))) return input}
原始程式碼應該可以在 32 位元架構上正常工作,因為它的填充(4 個位元組)與 minidumpapiset.h 使用的填充相符。
以上是Go 中帶有回呼的 MiniDumpWriteDump的詳細內容。更多資訊請關注PHP中文網其他相關文章!