Win32 API 日本語リファレンス
ホームSystem.Diagnostics.Debug › MINIDUMP_THREAD_CALLBACK

MINIDUMP_THREAD_CALLBACK

構造体
サイズx64: 944 バイト / x86: 940 バイトパッキング4

サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。

フィールド

フィールドサイズx64x86説明
ThreadIdDWORD4+0+0対象スレッドの識別子(スレッドID)を示す。
ThreadHandleHANDLE8/4+4+4対象スレッドのハンドル。OpenThread 等で得たハンドルを保持する。
ContextCONTEXT912+12+8スレッドのレジスタ状態を保持するコンテキストレコード。
SizeOfContextDWORD4+924+920Context が占めるバイト数を示す。
StackBaseULONGLONG8+928+924スレッドスタックの先頭(底)アドレスを示す。
StackEndULONGLONG8+936+932スレッドスタックの終端アドレスを示す。

各言語での定義

#include <windows.h>

// ARM64_NT_NEON128  (x64 16 / x86 16 バイト)
typedef struct ARM64_NT_NEON128 {
    _Anonymous_e__Struct Anonymous;
    DOUBLE D[2];
    FLOAT S[4];
    WORD H[8];
    BYTE B[16];
} ARM64_NT_NEON128;

// CONTEXT  (x64 912 / x86 912 バイト)
typedef struct CONTEXT {
    CONTEXT_FLAGS ContextFlags;
    DWORD Cpsr;
    _Anonymous_e__Union Anonymous;
    ULONGLONG Sp;
    ULONGLONG Pc;
    ARM64_NT_NEON128 V[32];
    DWORD Fpcr;
    DWORD Fpsr;
    DWORD Bcr[8];
    ULONGLONG Bvr[8];
    DWORD Wcr[2];
    ULONGLONG Wvr[2];
} CONTEXT;

// MINIDUMP_THREAD_CALLBACK  (x64 944 / x86 940 バイト)
#pragma pack(push, 4)
typedef struct MINIDUMP_THREAD_CALLBACK {
    DWORD ThreadId;
    HANDLE ThreadHandle;
    CONTEXT Context;
    DWORD SizeOfContext;
    ULONGLONG StackBase;
    ULONGLONG StackEnd;
} MINIDUMP_THREAD_CALLBACK;
#pragma pack(pop)
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ARM64_NT_NEON128
{
    public _Anonymous_e__Struct Anonymous;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public double[] D;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public float[] S;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public ushort[] H;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] B;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CONTEXT
{
    public uint ContextFlags;
    public uint Cpsr;
    public _Anonymous_e__Union Anonymous;
    public ulong Sp;
    public ulong Pc;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public ARM64_NT_NEON128[] V;
    public uint Fpcr;
    public uint Fpsr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public uint[] Bcr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public ulong[] Bvr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] Wcr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public ulong[] Wvr;
}

[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
public struct MINIDUMP_THREAD_CALLBACK
{
    public uint ThreadId;
    public IntPtr ThreadHandle;
    public CONTEXT Context;
    public uint SizeOfContext;
    public ulong StackBase;
    public ulong StackEnd;
}
Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure ARM64_NT_NEON128
    Public Anonymous As _Anonymous_e__Struct
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Public D() As Double
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Public S() As Single
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Public H() As UShort
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=16)> Public B() As Byte
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure CONTEXT
    Public ContextFlags As UInteger
    Public Cpsr As UInteger
    Public Anonymous As _Anonymous_e__Union
    Public Sp As ULong
    Public Pc As ULong
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=32)> Public V() As ARM64_NT_NEON128
    Public Fpcr As UInteger
    Public Fpsr As UInteger
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Public Bcr() As UInteger
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=8)> Public Bvr() As ULong
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Public Wcr() As UInteger
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Public Wvr() As ULong
End Structure

<StructLayout(LayoutKind.Sequential, Pack:=4, CharSet:=CharSet.Unicode)>
Public Structure MINIDUMP_THREAD_CALLBACK
    Public ThreadId As UInteger
    Public ThreadHandle As IntPtr
    Public Context As CONTEXT
    Public SizeOfContext As UInteger
    Public StackBase As ULong
    Public StackEnd As ULong
End Structure
import ctypes
from ctypes import wintypes

class ARM64_NT_NEON128(ctypes.Structure):
    _fields_ = [
        ("Anonymous", _Anonymous_e__Struct),
        ("D", ctypes.c_double * 2),
        ("S", ctypes.c_float * 4),
        ("H", ctypes.c_ushort * 8),
        ("B", ctypes.c_ubyte * 16),
    ]

class CONTEXT(ctypes.Structure):
    _fields_ = [
        ("ContextFlags", wintypes.DWORD),
        ("Cpsr", wintypes.DWORD),
        ("Anonymous", _Anonymous_e__Union),
        ("Sp", ctypes.c_ulonglong),
        ("Pc", ctypes.c_ulonglong),
        ("V", ARM64_NT_NEON128 * 32),
        ("Fpcr", wintypes.DWORD),
        ("Fpsr", wintypes.DWORD),
        ("Bcr", wintypes.DWORD * 8),
        ("Bvr", ctypes.c_ulonglong * 8),
        ("Wcr", wintypes.DWORD * 2),
        ("Wvr", ctypes.c_ulonglong * 2),
    ]

class MINIDUMP_THREAD_CALLBACK(ctypes.Structure):
    _pack_ = 4
    _fields_ = [
        ("ThreadId", wintypes.DWORD),
        ("ThreadHandle", ctypes.c_void_p),
        ("Context", CONTEXT),
        ("SizeOfContext", wintypes.DWORD),
        ("StackBase", ctypes.c_ulonglong),
        ("StackEnd", ctypes.c_ulonglong),
    ]
#[repr(C)]
pub struct ARM64_NT_NEON128 {
    pub Anonymous: _Anonymous_e__Struct,
    pub D: [f64; 2],
    pub S: [f32; 4],
    pub H: [u16; 8],
    pub B: [u8; 16],
}

#[repr(C)]
pub struct CONTEXT {
    pub ContextFlags: u32,
    pub Cpsr: u32,
    pub Anonymous: _Anonymous_e__Union,
    pub Sp: u64,
    pub Pc: u64,
    pub V: [ARM64_NT_NEON128; 32],
    pub Fpcr: u32,
    pub Fpsr: u32,
    pub Bcr: [u32; 8],
    pub Bvr: [u64; 8],
    pub Wcr: [u32; 2],
    pub Wvr: [u64; 2],
}

#[repr(C, packed(4))]
pub struct MINIDUMP_THREAD_CALLBACK {
    pub ThreadId: u32,
    pub ThreadHandle: *mut core::ffi::c_void,
    pub Context: CONTEXT,
    pub SizeOfContext: u32,
    pub StackBase: u64,
    pub StackEnd: u64,
}
import "golang.org/x/sys/windows"

type ARM64_NT_NEON128 struct {
	Anonymous _Anonymous_e__Struct
	D [2]float64
	S [4]float32
	H [8]uint16
	B [16]byte
}

type CONTEXT struct {
	ContextFlags uint32
	Cpsr uint32
	Anonymous _Anonymous_e__Union
	Sp uint64
	Pc uint64
	V [32]ARM64_NT_NEON128
	Fpcr uint32
	Fpsr uint32
	Bcr [8]uint32
	Bvr [8]uint64
	Wcr [2]uint32
	Wvr [2]uint64
}

type MINIDUMP_THREAD_CALLBACK struct {
	ThreadId uint32
	ThreadHandle uintptr
	Context CONTEXT
	SizeOfContext uint32
	StackBase uint64
	StackEnd uint64
}
type
  ARM64_NT_NEON128 = record
    Anonymous: _Anonymous_e__Struct;
    D: array[0..1] of Double;
    S: array[0..3] of Single;
    H: array[0..7] of Word;
    B: array[0..15] of Byte;
  end;

  CONTEXT = record
    ContextFlags: DWORD;
    Cpsr: DWORD;
    Anonymous: _Anonymous_e__Union;
    Sp: UInt64;
    Pc: UInt64;
    V: array[0..31] of ARM64_NT_NEON128;
    Fpcr: DWORD;
    Fpsr: DWORD;
    Bcr: array[0..7] of DWORD;
    Bvr: array[0..7] of UInt64;
    Wcr: array[0..1] of DWORD;
    Wvr: array[0..1] of UInt64;
  end;

  MINIDUMP_THREAD_CALLBACK = packed record
    ThreadId: DWORD;
    ThreadHandle: Pointer;
    Context: CONTEXT;
    SizeOfContext: DWORD;
    StackBase: UInt64;
    StackEnd: UInt64;
  end;
const ARM64_NT_NEON128 = extern struct {
    Anonymous: _Anonymous_e__Struct,
    D: [2]f64,
    S: [4]f32,
    H: [8]u16,
    B: [16]u8,
};

const CONTEXT = extern struct {
    ContextFlags: u32,
    Cpsr: u32,
    Anonymous: _Anonymous_e__Union,
    Sp: u64,
    Pc: u64,
    V: [32]ARM64_NT_NEON128,
    Fpcr: u32,
    Fpsr: u32,
    Bcr: [8]u32,
    Bvr: [8]u64,
    Wcr: [2]u32,
    Wvr: [2]u64,
};

const MINIDUMP_THREAD_CALLBACK = extern struct {
    ThreadId: u32,
    ThreadHandle: ?*anyopaque,
    Context: CONTEXT,
    SizeOfContext: u32,
    StackBase: u64,
    StackEnd: u64,
};
type
  ARM64_NT_NEON128 {.bycopy.} = object
    Anonymous: _Anonymous_e__Struct
    D: array[2, float64]
    S: array[4, float32]
    H: array[8, uint16]
    B: array[16, uint8]

  CONTEXT {.bycopy.} = object
    ContextFlags: uint32
    Cpsr: uint32
    Anonymous: _Anonymous_e__Union
    Sp: uint64
    Pc: uint64
    V: array[32, ARM64_NT_NEON128]
    Fpcr: uint32
    Fpsr: uint32
    Bcr: array[8, uint32]
    Bvr: array[8, uint64]
    Wcr: array[2, uint32]
    Wvr: array[2, uint64]

  MINIDUMP_THREAD_CALLBACK {.packed.} = object
    ThreadId: uint32
    ThreadHandle: pointer
    Context: CONTEXT
    SizeOfContext: uint32
    StackBase: uint64
    StackEnd: uint64
struct ARM64_NT_NEON128
{
    _Anonymous_e__Struct Anonymous;
    double[2] D;
    float[4] S;
    ushort[8] H;
    ubyte[16] B;
}

struct CONTEXT
{
    uint ContextFlags;
    uint Cpsr;
    _Anonymous_e__Union Anonymous;
    ulong Sp;
    ulong Pc;
    ARM64_NT_NEON128[32] V;
    uint Fpcr;
    uint Fpsr;
    uint[8] Bcr;
    ulong[8] Bvr;
    uint[2] Wcr;
    ulong[2] Wvr;
}

align(4)
struct MINIDUMP_THREAD_CALLBACK
{
    uint ThreadId;
    void* ThreadHandle;
    CONTEXT Context;
    uint SizeOfContext;
    ulong StackBase;
    ulong StackEnd;
}

HSP用 定義

HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。

; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x86 レイアウト)
; MINIDUMP_THREAD_CALLBACK サイズ: 940 バイト(x86)
dim st, 235    ; 4byte整数×235(構造体サイズ 940 / 4 切り上げ)
; ThreadId : DWORD (+0, 4byte)  st.0 = 値  /  値 = st.0   (lpoke/lpeek も可)
; ThreadHandle : HANDLE (+4, 4byte)  st.1 = 値  /  値 = st.1   (lpoke/lpeek も可)
; Context : CONTEXT (+8, 912byte)  varptr(st)+8 を基点に操作(912byte:入れ子/配列)
; SizeOfContext : DWORD (+920, 4byte)  st.230 = 値  /  値 = st.230   (lpoke/lpeek も可)
; StackBase : ULONGLONG (+924, 8byte)  qpoke st,924,値 / qpeek(st,924)  ※IronHSPのみ。3.7/3.8は lpoke st,924,下位 : lpoke st,928,上位
; StackEnd : ULONGLONG (+932, 8byte)  qpoke st,932,値 / qpeek(st,932)  ※IronHSPのみ。3.7/3.8は lpoke st,932,下位 : lpoke st,936,上位
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; MINIDUMP_THREAD_CALLBACK サイズ: 944 バイト(x64)
dim st, 236    ; 4byte整数×236(構造体サイズ 944 / 4 切り上げ)
; ThreadId : DWORD (+0, 4byte)  st.0 = 値  /  値 = st.0   (lpoke/lpeek も可)
; ThreadHandle : HANDLE (+4, 8byte)  qpoke st,4,値 / qpeek(st,4)  ※IronHSPのみ。3.7/3.8は lpoke st,4,下位 : lpoke st,8,上位
; Context : CONTEXT (+12, 912byte)  varptr(st)+12 を基点に操作(912byte:入れ子/配列)
; SizeOfContext : DWORD (+924, 4byte)  st.231 = 値  /  値 = st.231   (lpoke/lpeek も可)
; StackBase : ULONGLONG (+928, 8byte)  qpoke st,928,値 / qpeek(st,928)  ※IronHSPのみ。3.7/3.8は lpoke st,928,下位 : lpoke st,932,上位
; StackEnd : ULONGLONG (+936, 8byte)  qpoke st,936,値 / qpeek(st,936)  ※IronHSPのみ。3.7/3.8は lpoke st,936,下位 : lpoke st,940,上位
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
; ※GUID・入れ子構造体はデフォルト型でないため、依存する #defstruct を先に定義(下記に同梱)。
#defstruct global CONTEXT
    #field int ContextFlags
    #field int Cpsr
    #field byte Anonymous 248
    #field int64 Sp
    #field int64 Pc
    #field byte V 512
    #field int Fpcr
    #field int Fpsr
    #field int Bcr 8
    #field int64 Bvr 8
    #field int Wcr 2
    #field int64 Wvr 2
#endstruct

#defstruct global MINIDUMP_THREAD_CALLBACK, pack=4
    #field int ThreadId
    #field intptr ThreadHandle
    #field CONTEXT Context
    #field int SizeOfContext
    #field int64 StackBase
    #field int64 StackEnd
#endstruct

stdim st, MINIDUMP_THREAD_CALLBACK        ; NSTRUCT 変数を確保
st->ThreadId = 100
mes "ThreadId=" + st->ThreadId