try.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 294 行
C
294 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#define INCL_WINWINDOWMGR
#define INCL_WINFRAMEMGR
#define INCL_BASE
#define INCL_DOSDEVICES
#define INCL_DOSMEMMGR
#define INCL_DOSSIGNALS
#undef INCL_DOSINFOSEG
#undef INCL_DOSPROCESS
#define INCL_WINSWITCHLIST
#include "os2.h"
#define DBSEM_USER_SPECIFIED
#include "dbgapi.h"
#include <stddef.h>
#include <process.h>
#include <stdio.h>
#include "bsexcpt.h"
//#include "pmwin.h"
PID Pid = 0;
ULONG SID;
uDB_t Buff;
ULONG ExceptNum;
#define DBG_N_Breakpoint -100
#define DBG_N_SStep -101
#define DBG_N_Signal -102
void DebugExecute( uDB_t *buff, ULONG cmd )
{
EXCEPTIONREPORTRECORD ex;
ULONG value;
ULONG stopvalue;
ULONG notify=0;
BOOL got_second_notification;
ULONG fcp;
CONTEXTRECORD fcr;
buff->Cmd = cmd;
value = buff->Value;
if( cmd == DBG_C_Go ) {
value = 0;
}
stopvalue = XCPT_CONTINUE_EXECUTION;
got_second_notification = FALSE;
if( cmd == DBG_C_Stop ) {
stopvalue = XCPT_CONTINUE_STOP;
}
while( 1 ) {
buff->Value = value;
buff->Cmd = cmd;
DosDebug( buff );
value = stopvalue;
cmd = DBG_C_Continue;
/*
* handle the preemptive notifications
*/
switch( buff->Cmd ) {
case DBG_N_ModuleLoad:
// RecordModHandle( buff->Value );
break;
case DBG_N_ModuleFree:
break;
case DBG_N_NewProc:
break;
case DBG_N_ProcTerm:
value = XCPT_CONTINUE_STOP; /* halt us */
notify = DBG_N_ProcTerm;
break;
case DBG_N_ThreadCreate:
break;
case DBG_N_ThreadTerm:
break;
case DBG_N_AliasFree:
break;
case DBG_N_Exception:
if( buff->Value == DBG_X_STACK_INVALID ) {
value = XCPT_CONTINUE_SEARCH;
break;
}
fcp = buff->Len;
if( buff->Value == DBG_X_PRE_FIRST_CHANCE ) {
ExceptNum = buff->Buffer;
if( ExceptNum == XCPT_BREAKPOINT ) {
notify = DBG_N_Breakpoint;
value = XCPT_CONTINUE_STOP;
break;
} else if( ExceptNum == XCPT_SINGLE_STEP ) {
notify = DBG_N_SStep;
value = XCPT_CONTINUE_STOP;
break;
}
}
//
// NOTE: Going to second chance causes OS/2 to report the
// exception in the debugee. However, if you report
// the fault at the first chance notification, the
// debugee's own fault handlers will not get invoked!
//
value = XCPT_CONTINUE_SEARCH;
break;
default:
if( notify != 0 ) {
buff->Cmd = notify;
}
return;
}
}
}
extern long __far16 __pascal WinQueueFromID( long, short pid, short tid );
extern long __far16 __pascal WinReplyMsg( long, long, long, long );
extern long __far16 __pascal WinThreadAssocQueue( long, long );
extern long __far16 __pascal WinQuerySendMsg( long, long, long, void* );
HAB A;
HMQ Q;
HWND W;
int ThreadGone;
void HelpingHand( void *foo )
{
QMSG qmsg; /* Message from message queue */
short ok;
HMQ hmq;
foo=foo;
while( Q == 0 ) {
// printf( "watchdog here\n" );
fflush( stdout );
DosSleep( 10 );
}
ok = WinThreadAssocQueue( A, Q );
printf( "associate queue ok=%d, hab=%8.8x, hmq=%8.8x\n", ok, A, Q );
fflush( stdout );
while( Q != 0 ) {
fflush( stdout );
// if( WinPeekMsg( A, &qmsg, 0L, 0, 0, PM_REMOVE ) ) {
if( WinGetMsg( A, &qmsg, 0L, 0, 0 ) ) {
hmq = WinQueryWindowULong( qmsg.hwnd, QWL_HMQ );
printf( "MSG hwnd=%8.8x msg=%d\n", qmsg.hwnd, qmsg.msg );
fflush( stdout );
if( Q == hmq ) {
DosBeep( 1000, 250 );
printf( "interesting\r\n" );
fflush( stdout );
WinDefWindowProc( qmsg.hwnd, qmsg.msg, qmsg.mp1, qmsg.mp2 );
} else {
DosBeep( 500, 250 );
printf( "boring\r\n" );
fflush( stdout );
WinDispatchMsg( A, &qmsg );
}
}
}
ok = WinThreadAssocQueue( A, 0 );
printf( "queue dissociated %d\n", ok );
fflush( stdout );
ThreadGone=1;
_endthread();
}
main()
{
STARTDATA start;
int code;
SWCNTRL SW;
HSWITCH hswitch;
PPIB pib;
PTIB tib;
HMQ hmq;
HWND hwndme;
QMSG qmsg; /* Message from message queue */
int i;
_beginthread( HelpingHand, (void*)malloc( 10000 ), 10000, (void*)NULL );
DosGetInfoBlocks(&tib,&pib);
start.Length = offsetof( STARTDATA, IconFile ); /* default for the rest */
start.Related = 1;
start.FgBg = 1;
start.TraceOpt = 1;
start.PgmTitle = (PSZ) "Test Session";
start.PgmName = "HELLO.EXE";
start.PgmInputs = "hi there";
start.TermQ = 0;
start.Environment = NULL;
start.InheritOpt = 1;
start.SessionType = SSF_TYPE_PM;
// start.SessionType = SSF_TYPE_FULLSCREEN;
// start.SessionType = SSF_TYPE_WINDOWABLEVIO;
code = DosStartSession( &start, &SID, &Pid );
Buff.Pid = Pid;
Buff.Tid = 0;
Buff.Cmd = DBG_C_Connect;
Buff.Value = DBG_L_386;
DosDebug( &Buff );
Buff.Pid = Pid;
Buff.Tid = 1;
DebugExecute( &Buff, DBG_C_Stop );
if( Buff.Cmd != DBG_N_Success ) {
printf( "can't load task\n" );
fflush( stdout );
return;
}
printf( "Press a key to go to app\n" );
fflush( stdout );
// getch();
DosSelectSession( SID );
DebugExecute( &Buff, DBG_C_Go );
if( Buff.Cmd != DBG_N_Breakpoint ) {
printf( "didn't hit break\n" );
fflush( stdout );
return;
}
Buff.Cmd = DBG_C_Stop;
DosDebug( &Buff );
Buff.Cmd = DBG_C_ReadReg;
DosDebug( &Buff );
Buff.EIP++;
Buff.Cmd = DBG_C_WriteReg;
DosDebug( &Buff );
DosSelectSession( 0 );
hswitch = WinQuerySwitchHandle( 0, pib->pib_ulpid );
WinQuerySwitchEntry( hswitch, &SW );
A = WinQueryAnchorBlock( hwndme = SW.hwnd );
hmq = WinQueueFromID( A, pib->pib_ulpid, 1 );
printf( "me: hsw = %8.8x, hwnd = %8.8x, hab = %8.8x, hmq = %8.8x\n", hswitch, SW.hwnd, A, hmq );
fflush( stdout );
hswitch = WinQuerySwitchHandle( 0, Pid );
WinQuerySwitchEntry( hswitch, &SW );
W = SW.hwnd;
A = WinQueryAnchorBlock( W );
for( ;; ) {
hmq = WinQuerySendMsg( A, 0, Q, &qmsg );
if( hmq == 0 ) break;
printf( "SND hwnd=%8.8x msg=%d\n", qmsg.hwnd, qmsg.msg );
fflush( stdout );
WinReplyMsg( A, hmq, Q, 1 );
}
hmq = WinQueueFromID( A, Buff.Pid, Buff.Tid );
printf( "it: hsw = %8.8x, hwnd = %8.8x, hab = %8.8x, hmq = %8.8x\n", hswitch, W, A, hmq );
fflush( stdout );
Q = hmq;
printf( "press any key to post message to the app\n" );
getch();
WinPostMsg( W, WM_NULL, (MPARAM)0,(MPARAM)0 ); // testing
// WinPostMsg( W, WM_QUIT, (MPARAM)0,(MPARAM)0 );/* Cause termination*/
// printf( "sleeping\n" );
// DosSleep( 4000 );
// printf( "app running\n" );
// DebugExecute( &Buff, DBG_C_Go );
for( i = 0; i < 100; ++i ) {
DosSleep( 100 );
if( kbhit() ) break;
}
Q = 0;
// while( !ThreadGone ) DosSleep( 1 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?