Maison > développement back-end > Golang > MiniDumpWriteDump avec rappels dans Go

MiniDumpWriteDump avec rappels dans Go

王林
Libérer: 2024-02-05 23:51:03
avant
589 Les gens l'ont consulté

Go 中带有回调的 MiniDumpWriteDump

Contenu de la question

J'essaie d'implémenter MiniDumpWriteDump en utilisant callbacks dans Go.

Appelez 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)),
    )
Copier après la connexion

La fonction de rappelelle-même :

func miniDumpCallback(_ uintptr, CallbackInput *MINIDUMP_CALLBACK_INPUT, _ uintptr) uintptr {
    fmt.Println(CallbackInput.ProcessId, CallbackInput.CallbackType)
    return 1
}
Copier après la connexion

TypeDéfinition :

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
}
Copier après la connexion

Le rappel est appelé et certains champs reçoivent des données correctes, mais certains champs obtiennent des valeurs sans signification.

Par exemple, le rappel ci-dessus reçoit correctement le champ ProcessId de CallbackInput, mais reçoit un entier aléatoire comme l'énumération CallbackType MINIDUMP_CALLBACK_TYPE quand il le devrait.

Sortie :

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
Copier après la connexion


Bonne réponse


Comme les commentaires le suggèrent, le problème vient de l'alignement structurel.

Comme @IInspectable l'a expliqué, minidumpapiset.h, qui exporte la fonction MiniDumpWriteDump et la structure MINIDUMP_CALLBACK_INPUT, utilise l'alignement 4 octets strong> pour les architectures 32 bits et 64 bits, tandis que Go utilise 64 bits. par défaut 8 octets alignement, et ne fournit pas de moyen automatique de le modifier.

La solution est de lire la structure manuellement. Voici un exemple fonctionnel :

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}
Copier après la connexion
Le code original devrait fonctionner correctement sur les architectures 32 bits car son remplissage (4 octets) correspond au remplissage utilisé par minidumpapiset.h.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal