Question

Does anybody know where I can find some information about the fields of the CONTEXT structure in C++?

Was it helpful?

Solution

As @bcsanches states, this is a Windows API. It's going to be completely processor dependent. Look up the structure in your own headers.

On my headers it shows as:

//
// Context Frame
//
//  This frame has a several purposes: 1) it is used as an argument to
//  NtContinue, 2) is is used to constuct a call frame for APC delivery,
//  and 3) it is used in the user level thread creation routines.
//
//
// The flags field within this record controls the contents of a CONTEXT
// record.
//
// If the context record is used as an input parameter, then for each
// portion of the context record controlled by a flag whose value is
// set, it is assumed that that portion of the context record contains
// valid context. If the context record is being used to modify a threads
// context, then only that portion of the threads context is modified.
//
// If the context record is used as an output parameter to capture the
// context of a thread, then only those portions of the thread's context
// corresponding to set flags will be returned.
//
// CONTEXT_CONTROL specifies SegSs, Rsp, SegCs, Rip, and EFlags.
//
// CONTEXT_INTEGER specifies Rax, Rcx, Rdx, Rbx, Rbp, Rsi, Rdi, and R8-R15.
//
// CONTEXT_SEGMENTS specifies SegDs, SegEs, SegFs, and SegGs.
//
// CONTEXT_DEBUG_REGISTERS specifies Dr0-Dr3 and Dr6-Dr7.
//
// CONTEXT_MMX_REGISTERS specifies the floating point and extended registers
//     Mm0/St0-Mm7/St7 and Xmm0-Xmm15).
//

typedef struct DECLSPEC_ALIGN(16) _CONTEXT {

    //
    // Register parameter home addresses.
    //
    // N.B. These fields are for convience - they could be used to extend the
    //      context record in the future.
    //

    DWORD64 P1Home;
    DWORD64 P2Home;
    DWORD64 P3Home;
    DWORD64 P4Home;
    DWORD64 P5Home;
    DWORD64 P6Home;

    //
    // Control flags.
    //

    DWORD ContextFlags;
    DWORD MxCsr;

    //
    // Segment Registers and processor flags.
    //

    WORD   SegCs;
    WORD   SegDs;
    WORD   SegEs;
    WORD   SegFs;
    WORD   SegGs;
    WORD   SegSs;
    DWORD EFlags;

    //
    // Debug registers
    //

    DWORD64 Dr0;
    DWORD64 Dr1;
    DWORD64 Dr2;
    DWORD64 Dr3;
    DWORD64 Dr6;
    DWORD64 Dr7;

    //
    // Integer registers.
    //

    DWORD64 Rax;
    DWORD64 Rcx;
    DWORD64 Rdx;
    DWORD64 Rbx;
    DWORD64 Rsp;
    DWORD64 Rbp;
    DWORD64 Rsi;
    DWORD64 Rdi;
    DWORD64 R8;
    DWORD64 R9;
    DWORD64 R10;
    DWORD64 R11;
    DWORD64 R12;
    DWORD64 R13;
    DWORD64 R14;
    DWORD64 R15;

    //
    // Program counter.
    //

    DWORD64 Rip;

    //
    // Floating point state.
    //

    union {
        XMM_SAVE_AREA32 FltSave;
        struct {
            M128A Header[2];
            M128A Legacy[8];
            M128A Xmm0;
            M128A Xmm1;
            M128A Xmm2;
            M128A Xmm3;
            M128A Xmm4;
            M128A Xmm5;
            M128A Xmm6;
            M128A Xmm7;
            M128A Xmm8;
            M128A Xmm9;
            M128A Xmm10;
            M128A Xmm11;
            M128A Xmm12;
            M128A Xmm13;
            M128A Xmm14;
            M128A Xmm15;
        };
    };

    //
    // Vector registers.
    //

    M128A VectorRegister[26];
    DWORD64 VectorControl;

    //
    // Special debug control registers.
    //

    DWORD64 DebugControl;
    DWORD64 LastBranchToRip;
    DWORD64 LastBranchFromRip;
    DWORD64 LastExceptionToRip;
    DWORD64 LastExceptionFromRip;
} CONTEXT, *PCONTEXT;

but it may be different for your platform. Note that if you write code that depends on any particular version of the CONTEXT structure, your code won't compile when you target another platform, such as attempting to build for x86 from x64 code or vice versa.

You should really treat this structure as an opaque object unless you have a really good (Note: Most reasons aren't really good) reason to do otherwise. This stuff's supposed to be contained within the bowels of hal.dll, ntoskrnl.exe, and ntdll.dll, not your code.

OTHER TIPS

It says right in the documentation:

Contains processor-specific register data. The system uses CONTEXT structures to perform various internal operations. Refer to the header file WinNT.h for definitions of this structure for each processor architecture.

So you need to check your platform. Find the definition within WinNT.h.

Unless you are writing code in assembly language and then want to write an exception handler in assembly language, you should have no use or need for information about CONTEXT structure contents.

If you do want to write logic in assembly code and want to call it from C++, and you want to use exception handling (such as to catch divisions by zero or SSE exceptions, which probably should be prevented through schemes like data validation anyway), then you're probably better off leaving the exception handling to the C++ code that is calling your assembly language procedure.

That'll be far less messy because then you won't have to fuss with what the C++ code does for its part concerning exception handling. It is far easier and simpler to just make your assembly code logic work so it prevents exceptions from being thrown. Besides that, it should make your code significantly more efficient and graceful in how it handles problems.

Mind you, exception handling mechanisms were invented to serve as a safety net and as a measure of last resort to save software from simply crashing and burning extravagantly when something weird and unexpected happens. Throwing exceptions should be the exception rather than the rule, hence them being named "exceptions".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top