首頁  >  文章  >  後端開發  >  Go 中帶有回呼的 MiniDumpWriteDump

Go 中帶有回呼的 MiniDumpWriteDump

王林
王林轉載
2024-02-05 23:51:03459瀏覽

Go 中带有回调的 MiniDumpWriteDump

問題內容

我正在嘗試在​​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
}

回呼被調用,一些字段收到正確的數據,但一些字段得到無意義值。

例如,上面的回調正確接收CallbackInputProcessId 字段,但在應該接收時接收隨機整數作為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中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除