首页  >  文章  >  后端开发  >  Go 中带有回调的 MiniDumpWriteDump

Go 中带有回调的 MiniDumpWriteDump

王林
王林转载
2024-02-05 23:51:03457浏览

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删除