This call provides an interface into the OS/2 kernel to facilitate program debugging.
DosPtrace
PtraceB (PBYTE) - output
DosPtrace allows a parent process to control the execution of another process by implementing breakpoint debugging for a debugger. Both the program under test and the program being debugged must be executing in OS/2 mode.
DosPtrace supports debugging of a process with multiple threads by allowing the debugger to read and write registers, freeze and resume thread execution, and get status on the threads.
The debugger must be able to read and write the instructions, data, and registers of the program being debugged to insert breakpoint instructions. When a process runs in OS/2 mode, one process cannot directly manipulate the address space of another process. OS/2 controls this address space through the use of the trace flag facility in DosExecPgm and the Ptrace buffer in DosPtrace.
The steps to program debugging in OS/2 mode follow:
To debug a process with multiple threads, set a field in the Ptrace buffer (Ptrace_B.TID) to the thread ID of the thread of interest. This causes the read/write register commands to receive only the register set of the specified thread.
Note: For a process with multiple threads, the address space is the same for all the threads in the process. When commands are issued to read/write memory locations or set breakpoints, they affect all the threads in the process, even when a command is issued with a specific thread ID.
The debugger may suspend and resume specific threads through use of the TRC_C_Freeze and TRC_C_Resume commands. Having only selected threads be affected by the breakpoints is useful for manipulating them while other threads are suspended.
When a process debugger terminates, the program being debugged also terminates. To accomplish this, an internal link between the debugger and the program being debugged is maintained. This link is established as a result of the first successful DosPtrace command. Once established, this link can not be reset.
The process being debugged does not need to be a direct child process. In this situation, a small window of time exists between the DosExecPgm call and the first DosPtrace call. If the debugger terminates during this window, the program being debugged cannot be cleaned up. The system automatically terminates the program that was to be debugged.
Specifying a trace option of 2 with DosStartSession enables a debugger running in the parent session to trace all processes associated with an application running in the child session, regardless of whether the process was started by DosStartSession request or by DosExecPgm. See DosStartSession for more information.
Contents of the Ptrace Buffer:
┌──────────┬────┬────┬──────────────────────────────────────────────────┐ │ PTRACE_B │ │ │ STRUCTURE │ ├──────────┼────┼────┼──────────────────────────────────────────────────┤ │ PID │ DW │ 0 │ ; Process ID of the process being debugged │ ├──────────┼────┼────┼──────────────────────────────────────────────────┤ │ TID │ DW │ 0 │ ; Thread ID of the process being debugged │ ├──────────┼────┼────┼──────────────────────────────────────────────────┤ │ Cmd │ DW │ 0 │ ; Request to DosPtrace, or DosPtrace result code │ ├──────────┼────┼────┼──────────────────────────────────────────────────┤ │ Value │ DW │ ? │ ; Data to DosPtrace, or DosPtrace error code │ ├──────────┼────┼────┼──────────────────────────────────────────────────┤ │ OffV │ DW │ ? │ ; Offset value │ ├──────────┼────┼────┼──────────────────────────────────────────────────┤ │ SegV │ DW │ ? │ ; Segment value │ ├──────────┼────┼────┼──────────────────────────────────────────────────┤ │ MTE │ DW │ ? │ ; Library Module handle │ ├──────────┼────┼────┼──────────────────────────────────────────────────┤ │ Ptrace B │ │ │ │ │ ENDS │ │ │ │ └──────────┴────┴────┴──────────────────────────────────────────────────┘
Exceptions:
┌───────────┬────┬────┬──────────────────────────────────┐ │ PTRACEREGS│ │ │ STRUCTURE │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rAX │ DW │ ? │ ; Registers AX through SS │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rBX │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rCX │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rDX │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rSI │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rDI │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rBP │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rDS │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rES │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rIP │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rCS │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rF │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rSP │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ rSS │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ Ptraceregs│ │ │ │ │ ENDS │ │ │ │ └───────────┴────┴────┴──────────────────────────────────┘
For the TRC_C_ReadMemB and TRC_C_WriteMemB commands, the remainder of the Ptrace buffer contains:
┌───────────┬────┬────┬──────────────────────────────────┐ │ PTRACEPTR │ │ │ STRUCTURE │ ├───────────┼────┼────┼──────────────────────────────────┤ │ OffB │ DW │ ? │ ; Buffer Address │ ├───────────┼────┼────┼──────────────────────────────────┤ │ SegB │ DW │ ? │ │ ├───────────┼────┼────┼──────────────────────────────────┤ │ Ptraceptr │ │ │ │ │ ENDS │ │ │ │ └───────────┴────┴────┴──────────────────────────────────┘
DosPtrace Commands: PTrace_B.Cmd must contain one of the following commands
upon entrance to DosPtrace:
┌───────────────────┬─────────┬───────────────────┬──────────────────┐ │ TRC_C_Null │ EQU 0 │ │ ; Invalid │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_ReadMem_I │ EQU 1 │ │ ; Instruction │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_ReadMem_D │ EQU 2 │ │ ; Data │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_ReadMem │ EQU │ TRC_C_ReadMem_I │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_ReadReg │ EQU 3 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_WriteMem_I │ EQU 4 │ │ ; Instruction │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_WriteMem_D │ EQU 5 │ │ ; Data │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_WriteMem │ EQU │ TRC_C_WriteMem_I │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_WriteReg │ EQU 6 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_Go │ EQU 7 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_Term │ EQU 8 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_SStep │ EQU 9 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_Stop │ EQU 10 │ │ ; Initialize │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_Freeze │ EQU 11 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_Resume │ EQU 12 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_NumToSel │ EQU 13 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_GetFPRegs │ EQU 14 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_SetFPRegs │ EQU 15 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_GetLibName │ EQU 16 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_ThrdStat │ EQU 17 │ │ │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_ReadMem_B │ EQU 18 │ │ ; Read Block │ ├───────────────────┼─────────┼───────────────────┼──────────────────┤ │ TRC_C_WriteMem_B │ EQU 19 │ │ ; Write Block │ └───────────────────┴─────────┴───────────────────┴──────────────────┘
Commands and Required Input: A command is issued by placing the command number in Ptrace buffer, and calling DosPtrace with that buffer.
All of the commands require that Ptrace_B.PID be the PID of the process to debug.
TRC_C_Null
Memory Operations:
TRC_C_ReadMem_I
TRC_C_ReadMem_B
o
TRC_C_Go
For TRC_C_GetLibName, SegV:OffV should point to a buffer where the name of the library is returned. PTrace_B.Value should hold the library's module handle (MTE).
TRC_C_NumToSel
The layout of this area is described in the NPX287 manual under the heading FSAVE/FRSTOR memory layout.
TRC_C_GetFPRegs
┌────────────────┬──────────┬────────────────┐ │ TRC_C_SUC_ret │ EQU 0 │ ; Success │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_ERR_ret │ EQU -1 │ ; Error │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_SIG_ret │ EQU -2 │ ; Signal │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_TBT_ret │ EQU -3 │ ; Single Step │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_BPT_ret │ EQU -4 │ ; Breakpoint │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_NMI_ret │ EQU -5 │ ; Parity Error │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_KIL_ret │ EQU -6 │ ; Process │ │ │ │ dying │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_GPF_ret │ EQU -7 │ ; GP fault │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_LIB_ret │ EQU -8 │ ; Library load │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_FPE_ret │ EQU -9 │ ; FP error │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_THD_ret │ EQU -10 │ ; Thread │ │ │ │ ending │ ├────────────────┼──────────┼────────────────┤ │ TRC_C_STP_ret │ EQU -11 │ ; Async. Stop. │ └────────────────┴──────────┴────────────────┘
TRACE_BAD_COMMAND