Maison >développement back-end >Golang >MiniDumpWriteDump avec rappels dans Go
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)), )
La fonction de rappelelle-même :
func miniDumpCallback(_ uintptr, CallbackInput *MINIDUMP_CALLBACK_INPUT, _ uintptr) uintptr { fmt.Println(CallbackInput.ProcessId, CallbackInput.CallbackType) return 1 }
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 }
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
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}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!