DosQueryThreadContext

From EDM2
Jump to: navigation, search

Query context of a suspended thread.

Syntax

DosQueryThreadContext(tid, level, pcxt)

Parameters

tid (TID) - input
Thread identity.
level (ULONG) - input
Level of information desired:
CONTEXT_CONTROL (0x00000001) Control registers: SS:ESP, CS:EIP, EFLAGS and EBP
CONTEXT_INTEGER (0x00000002) EAX, EBX, ECX, EDX, ESI and EDI
CONTEXT_SEGMENTS (0x00000004) Segment registers: DS, ES, FS, and GS
CONTEXT_FLOATING_POINT (0x00000008) Numeric coprocessor state
CONTEXT_FULL All of the above
pcxt (PCONTEXTRECORD) - in/out
Thread context record.

Return Code

ulrc (APIRET) - returns
DosQueryThreadContext returns one of the following values:
  • 0 NO_ERROR
  • 87 ERROR_INVALID_PARAMETER
  • 90 ERROR_NOT_FROZEN
  • 115 ERROR_PROTECTION_VIOLATION
  • 309 ERROR_INVALID_THREADID

Remarks

DosQueryThreadContext returns the context record of a suspended thread. A thread may be suspended by using DosSuspendThread or DosEnterCritSec. If DosSuspendThread is used, the caller must allow some time for OS/2 to suspend the thread before querying its context.

Note: Values from the thread context should be used only when the state of the target thread is known.

Example Code

This example uses DosQueryThreadContext to query the context of a suspended thread.

#define INCL_DOSEXCEPTIONS
#define INCL_DOSPROCESS
#define INCL_DOSERRORS
#include <os2.h>
#include <stdio.h>

VOID _System CntThreadProc( ULONG LoopMax );             /* Count Thread */
VOID PrintContextRecord( CONTEXTRECORD *pThread );

int main(VOID)
{
    TID        tidCntThread = 0;   /* ID returned for newly created thread */
    PFNTHREAD  pfnCntThread = &CntThreadProc; /* Address of Thread program */
    ULONG      ulLoopMax    = 500000;     /* Parameter to thread routine   */
    APIRET     rc           = NO_ERROR;   /* Return code                   */

                      /* Thread Context Record */
    CONTEXTRECORD  Thread_cxt= {0,{0,0,0,0,0,0,0},
                               {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},
                                {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},
                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    rc = DosCreateThread(&tidCntThread,  /* Thread ID (return by function) */
                         pfnCntThread,   /* Address of thread program      */
                         ulLoopMax,      /* Parameter passed to ThreadProc */
                         CREATE_READY |  /* Thread is ready when created   */
                         STACK_SPARSE,   /* Do not pre_commit stack pages  */
                         8192L);         /* Stack size, rounded to page bdy*/
    if (rc != NO_ERROR) {
        printf("DosCreateThread error: return code = %u\n",rc);
        return 1;
    }

    rc = DosSuspendThread (tidCntThread);
    if (rc != NO_ERROR)
        printf("DosSuspendThread error: return code = %u\n",rc);
    else
    {           /* Wait for thread to suspend */

        printf("Waiting 5 seconds for thread to suspend...\n");
        rc = DosSleep(5000);

        rc = DosQueryThreadContext (tidCntThread,
                                    CONTEXT_FULL,
                                    &Thread_cxt);
        if (rc != NO_ERROR)
           printf("DosQueryThreadContext error: return code = %u\n",rc);
        else
           PrintContextRecord( &Thread_cxt );


        rc = DosResumeThread (tidCntThread);
        if (rc != NO_ERROR) {
            printf("DosResumeThread error: return code = %u\n",rc);
            return 1;
        }
    }

    printf("Waiting for thread to complete...\n");

    rc = DosWaitThread ( &tidCntThread, DCWW_WAIT );
    if (rc != NO_ERROR) {
        printf("DosWaitThread error: return code = %u\n",rc);
        return 1;
    }

    printf("Thread has completed!\n");
    return NO_ERROR;
}

VOID _System CntThreadProc( ULONG LoopMax ) /* Count Thread */
{
    ULONG  ulCount = 0,
           i       = 0,
           j       = 1,
           k       = 1,
           l       = 0;
    double w       = 0.0,
           y       = 0.0,
           z       = 0.0;

    for (l=0; l < 20; l++)
    {
      for (i=0; i < LoopMax; i++)
      {
        w = 1.00 / 2.00;
        y = 2.00 * 2.00;
        z = 3.00 / 6.00;
        j = j + i;
        k = k * i;
      }
    }

  return;
}

VOID PrintContextRecord( CONTEXTRECORD *pThread )
{
       int i = 0;

       printf("\nRegisters for CONTEXT_CONTROL level:\n");
       printf("  EBP= 0x%08x\t",pThread->ctx_RegEbp);
       printf("EIP= 0x%08x\t",pThread->ctx_RegEip);
       printf("CS= 0x%08x\n",pThread->ctx_SegCs);
       printf("  EFLAGS = 0x%08x\t",pThread->ctx_EFlags);
       printf("ESP= 0x%08x\t",pThread->ctx_RegEsp);
       printf("SS= 0x%08x\n",pThread->ctx_SegSs);

       printf("\nRegisters for CONTEXT_INTEGER level:\n");
       printf("  EAX= 0x%08x\t",pThread->ctx_RegEax);
       printf("EBX= 0x%08x\t",pThread->ctx_RegEbx);
       printf("ECX= 0x%08x\n",pThread->ctx_RegEcx);
       printf("  EDX= 0x%08x\t",pThread->ctx_RegEdx);
       printf("ESI= 0x%08x\t",pThread->ctx_RegEsi);
       printf("EDI= 0x%08x\n",pThread->ctx_RegEdi);

       printf("\nRegisters for CONTEXT_SEGMENTS level:\n");
       printf("  DS= 0x%08x\t",pThread->ctx_SegDs);
       printf("ES= 0x%08x\t",pThread->ctx_SegEs);
       printf("FS= 0x%08x\t",pThread->ctx_SegFs);
       printf("GS= 0x%08x\n",pThread->ctx_SegGs);

       printf("\nRegisters for CONTEXT_FLOATING_POINT level:\n");
       printf("  - Coprocessor stack register (exponent,hisig:losig):\n");
       for (i=0;i<8;i++)
       {
          printf("    ctx_stack[%d]=0x%08x ,0x%08x :0x%08x \n",i,
                  pThread->ctx_stack[i].signexp,
                  pThread->ctx_stack[i].hisig,
                  pThread->ctx_stack[i].losig);
       }
       printf("  - Other element\n");
       for (i=0;i<7;i++)
       {
          printf("    ctx_env[%d]=0x%08x \n",i ,pThread->ctx_env[i]);
       }

       return;
}

Related Functions