Rumah  >  Artikel  >  pembangunan bahagian belakang  >  MiniDumpWriteDump dengan panggilan balik dalam Go

MiniDumpWriteDump dengan panggilan balik dalam Go

王林
王林ke hadapan
2024-02-05 23:51:03459semak imbas

Go 中带有回调的 MiniDumpWriteDump

Kandungan soalan

Saya cuba melaksanakan MiniDumpWriteDump menggunakan panggilan balik dalam Go.

Panggil 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)),
    )

Fungsi panggilan balik itu sendiri:

func miniDumpCallback(_ uintptr, CallbackInput *MINIDUMP_CALLBACK_INPUT, _ uintptr) uintptr {
    fmt.Println(CallbackInput.ProcessId, CallbackInput.CallbackType)
    return 1
}

JenisDefinisi:

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
}

Panggil balik dipanggil dan sesetengah medan menerima data yang betul, tetapi sesetengah medan mendapat nilai tidak bermakna.

Sebagai contoh, panggilan balik di atas dengan betul menerima medan ProcessId CallbackInput, tetapi menerima integer rawak sebagai CallbackType MINIDUMP_CALLBACK_TYPE.penghitungan apabila ia sepatutnya.

Keluaran:

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

Jawapan betul


Seperti yang dicadangkan oleh komen, masalahnya ialah penjajaran struktur.

Seperti yang dijelaskan oleh @IInspectable, minidumpapiset.h, yang mengeksport fungsi MiniDumpWriteDump dan struktur MINIDUMP_CALLBACK_INPUT, menggunakan penjajaran 4-bait kuat> untuk kedua-dua 32-bit dan 4 seni bina 4 dan 4 Go. secara lalai penjajaran

8-bait

, dan tidak menyediakan cara automatik untuk menukarnya.

Penyelesaian adalah membaca struktur secara manual. Berikut ialah contoh yang berfungsi:

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}
🎜Kod asal harus berfungsi dengan baik pada seni bina 32-bit kerana paddingnya (4 bait) sepadan dengan padding yang digunakan oleh minidumpapiset.h. 🎜

Atas ialah kandungan terperinci MiniDumpWriteDump dengan panggilan balik dalam Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam