hotspot/agent/src/os/win32/SwDbgSub.cpp
author never
Mon, 04 May 2009 22:06:47 -0700
changeset 2744 57f0579fbe09
parent 1 489c9b5090e2
child 5547 f4b087cbb361
permissions -rw-r--r--
6837224: libsaproc.so on linux needs version of 6799141 Reviewed-by: kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2000-2003 Sun Microsystems, Inc.  All Rights Reserved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
// This is the source code for the subprocess forked by the Simple
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
// Windows Debug Server. It assumes most of the responsibility for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
// debug session, and processes all of the commands sent by clients.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
// Disable too-long symbol warnings
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
#pragma warning ( disable : 4786 )
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
#include <iostream>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
#include <vector>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
#include <stdlib.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
#include <assert.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
// Must come before windows.h
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
#include <winsock2.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
#include <windows.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
#include "IOBuf.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
#include "libInfo.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
#include "LockableList.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
#include "Message.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
#include "Monitor.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
#include "nt4internals.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
// Uncomment the #define below to get messages on stderr
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
// #define DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
using namespace std;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
DWORD pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
HANDLE procHandle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
IOBuf* ioBuf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
// State flags indicating whether the attach to the remote process
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
// definitively succeeded or failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
volatile bool attachFailed    = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
volatile bool attachSucceeded = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
// State flag indicating whether the target process is suspended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
// Modified by suspend()/resume(), viewed by debug thread, but only
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
// under cover of the threads lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
volatile bool suspended       = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
// State flags indicating whether we are considered to be attached to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
// the target process and are therefore queuing up events to be sent
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
// back to the debug server. These flags are only accessed and
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
// modified under the cover of the eventLock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
Monitor* eventLock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
// The following is set to true when a client is attached to this process
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
volatile bool generateDebugEvents = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
// Pointer to current debug event; non-NULL indicates a debug event is
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
// waiting to be sent to the client. Main thread sets this to NULL to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
// indicate that the event has been consumed; also sets
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
// passEventToClient, below.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
volatile DEBUG_EVENT* curDebugEvent = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
// Set by main thread to indicate whether the most recently posted
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
// debug event should be passed on to the target process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
volatile bool passEventToClient = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
void conditionalPostDebugEvent(DEBUG_EVENT* ev, DWORD* continueOrNotHandledFlag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  // FIXME: make it possible for the client to enable and disable
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  // certain types of events (have to do so in a platform-independent
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  // manner)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  switch (ev->dwDebugEventCode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
  case EXCEPTION_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
    switch (ev->u.Exception.ExceptionRecord.ExceptionCode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
    case EXCEPTION_BREAKPOINT:  break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
    case EXCEPTION_SINGLE_STEP: break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    case EXCEPTION_ACCESS_VIOLATION: break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    default: return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  eventLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  if (generateDebugEvents) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    curDebugEvent = ev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
    while (curDebugEvent != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
      eventLock->wait();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    if (passEventToClient) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      *continueOrNotHandledFlag = DBG_EXCEPTION_NOT_HANDLED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
      *continueOrNotHandledFlag = DBG_CONTINUE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  eventLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
//----------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
// Module list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
vector<LibInfo> libs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
//----------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
// Thread list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
struct ThreadInfo {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  DWORD tid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  HANDLE thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  ThreadInfo(DWORD tid, HANDLE thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
    this->tid = tid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    this->thread = thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
class ThreadList : public LockableList<ThreadInfo> {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  bool removeByThreadID(DWORD tid) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
    for (InternalListType::iterator iter = internalList.begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
         iter != internalList.end(); iter++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
      if ((*iter).tid == tid) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
        internalList.erase(iter);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  HANDLE threadIDToHandle(DWORD tid) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
    for (InternalListType::iterator iter = internalList.begin();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
         iter != internalList.end(); iter++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
      if ((*iter).tid == tid) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
        return (*iter).thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
ThreadList threads;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
//----------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
// INITIALIZATION AND TERMINATION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
printError(const char* prefix) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  DWORD detail = GetLastError();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
  LPTSTR message;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
                FORMAT_MESSAGE_FROM_SYSTEM,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
                0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
                detail,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
                0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
                (LPTSTR) &message,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
                1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
                NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  // FIXME: This is signaling an error: "The handle is invalid." ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  // Do I have to do all of my WaitForDebugEvent calls from the same thread?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  cerr << prefix << ": " << message << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  LocalFree(message);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
endProcess(bool waitForProcess = true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  NT4::unloadNTDLL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  if (waitForProcess) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    // Though we're exiting because of an error, do not tear down the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    // target process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    WaitForSingleObject(procHandle, INFINITE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
  CloseHandle(procHandle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
  exit(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
DWORD WINAPI
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
debugThreadEntry(void*) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  DWORD lastMsgId = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  int count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  if (!DebugActiveProcess(pid)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    attachFailed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  // Wait for debug events. We keep the information from some of these
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  // on the side in anticipation of later queries by the client. NOTE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  // that we leave the process running. The main thread is responsible
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  // for suspending and resuming all currently-active threads upon
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  // client attach and detach.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
    DEBUG_EVENT ev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
    if (!WaitForDebugEvent(&ev, INFINITE)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
      if (++count < 10) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
        // FIXME: This is signaling an error: "The handle is invalid." ?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
        // Do I have to do all of my WaitForDebugEvent calls from the same thread?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
        printError("WaitForDebugEvent failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
      if (ev.dwDebugEventCode != lastMsgId) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
        lastMsgId = ev.dwDebugEventCode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
        count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
        cerr << "Debug thread received event " << ev.dwDebugEventCode << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
        if (++count < 10) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
          cerr << "Debug thread received event " << ev.dwDebugEventCode << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
      DWORD dbgContinueMode = DBG_CONTINUE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
      switch (ev.dwDebugEventCode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
      case LOAD_DLL_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
        conditionalPostDebugEvent(&ev, &dbgContinueMode);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
      case UNLOAD_DLL_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
        conditionalPostDebugEvent(&ev, &dbgContinueMode);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
      case CREATE_PROCESS_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
        threads.lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
        // FIXME: will this deal properly with child processes? If
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
        // not, is it possible to make it do so?
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
        cerr << "CREATE_PROCESS_DEBUG_EVENT " << ev.dwThreadId
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
             << " " << ev.u.CreateProcessInfo.hThread << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
        if (ev.u.CreateProcessInfo.hThread != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
          threads.add(ThreadInfo(ev.dwThreadId, ev.u.CreateProcessInfo.hThread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
        threads.unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
      case CREATE_THREAD_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
        threads.lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
        cerr << "CREATE_THREAD_DEBUG_EVENT " << ev.dwThreadId
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
             << " " << ev.u.CreateThread.hThread << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
        if (suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
          // Suspend this thread before adding it to the thread list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
          SuspendThread(ev.u.CreateThread.hThread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
        threads.add(ThreadInfo(ev.dwThreadId, ev.u.CreateThread.hThread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
        threads.unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      case EXIT_THREAD_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
        threads.lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
        cerr << "EXIT_THREAD_DEBUG_EVENT " << ev.dwThreadId << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
        threads.removeByThreadID(ev.dwThreadId);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
        threads.unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
      case EXCEPTION_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
        //      cerr << "EXCEPTION_DEBUG_EVENT" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
        switch (ev.u.Exception.ExceptionRecord.ExceptionCode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
        case EXCEPTION_BREAKPOINT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
          //        cerr << "EXCEPTION_BREAKPOINT" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
          if (!attachSucceeded && !attachFailed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
            attachSucceeded = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
        default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
          dbgContinueMode = DBG_EXCEPTION_NOT_HANDLED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
        conditionalPostDebugEvent(&ev, &dbgContinueMode);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
      case EXIT_PROCESS_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
        endProcess(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
        // NOT REACHED
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
        cerr << "Received debug event " << ev.dwDebugEventCode << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
      ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, dbgContinueMode);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
bool
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
attachToProcess() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  // Create event lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
  eventLock = new Monitor();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
  // Get a process handle for later
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  procHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  if (procHandle == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  // Start up the debug thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  DWORD debugThreadId;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  if (CreateThread(NULL, 0, &debugThreadEntry, NULL, 0, &debugThreadId) == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    // Failed to make background debug thread. Fail.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  while ((!attachSucceeded) && (!attachFailed)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    Sleep(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  if (attachFailed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
  assert(attachSucceeded);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
bool
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
readMessage(Message* msg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  DWORD numRead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
                msg,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
                sizeof(Message),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
                &numRead,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
                NULL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  if (numRead != sizeof(Message)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  // For "poke" messages, must follow up by reading raw data
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  if (msg->type == Message::POKE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    char* dataBuf = new char[msg->pokeArg.numBytes];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
    if (dataBuf == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
                  dataBuf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
                  msg->pokeArg.numBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
                  &numRead,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
                  NULL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
      delete[] dataBuf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
    if (numRead != msg->pokeArg.numBytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
      delete[] dataBuf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
    msg->pokeArg.data = (void *) dataBuf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
handlePeek(Message* msg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
  cerr << "Entering handlePeek()" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  char* memBuf = new char[msg->peekArg.numBytes];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  if (memBuf == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
    ioBuf->writeString("B");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
    ioBuf->writeBinChar(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
    ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
    delete[] memBuf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  // Try fast case first
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
  DWORD numRead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  BOOL res = ReadProcessMemory(procHandle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
                               (LPCVOID) msg->peekArg.address,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
                               memBuf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
                               msg->peekArg.numBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
                               &numRead);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  if (res && (numRead == msg->peekArg.numBytes)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
    // OK, complete success. Phew.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
    cerr << "Peek success case" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
    ioBuf->writeString("B");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    ioBuf->writeBinChar(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    ioBuf->writeBinUnsignedInt(numRead);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
    ioBuf->writeBinChar(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
    ioBuf->writeBinBuf(memBuf, numRead);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    cerr << "*** Peek slow case ***" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    ioBuf->writeString("B");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
    ioBuf->writeBinChar(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    // Use VirtualQuery to speed things up a bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
    DWORD numLeft = msg->peekArg.numBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
    char* curAddr = (char*) msg->peekArg.address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    while (numLeft > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
      MEMORY_BASIC_INFORMATION memInfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
      VirtualQueryEx(procHandle, curAddr, &memInfo, sizeof(memInfo));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
      DWORD numToRead = memInfo.RegionSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
      if (numToRead > numLeft) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
        numToRead = numLeft;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
      DWORD numRead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
      if (memInfo.State == MEM_COMMIT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
        // Read the process memory at this address for this length
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
        // FIXME: should check the result of this read
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
        ReadProcessMemory(procHandle, curAddr, memBuf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
                          numToRead, &numRead);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
        // Write this out
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
        cerr << "*** Writing " << numToRead << " bytes as mapped ***" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
        ioBuf->writeBinUnsignedInt(numToRead);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
        ioBuf->writeBinChar(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
        ioBuf->writeBinBuf(memBuf, numToRead);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
        // Indicate region is free
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
        cerr << "*** Writing " << numToRead << " bytes as unmapped ***" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
        ioBuf->writeBinUnsignedInt(numToRead);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
        ioBuf->writeBinChar(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
      curAddr += numToRead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
      numLeft -= numToRead;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  delete[] memBuf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
  cerr << "Exiting handlePeek()" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
handlePoke(Message* msg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
  cerr << "Entering handlePoke()" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  DWORD numWritten;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
  BOOL res = WriteProcessMemory(procHandle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
                                (LPVOID) msg->pokeArg.address,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
                                msg->pokeArg.data,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
                                msg->pokeArg.numBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
                                &numWritten);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
  if (res && (numWritten == msg->pokeArg.numBytes)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    // Success
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
    ioBuf->writeBoolAsInt(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
    cerr << " (Succeeded)" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
    // Failure
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
    ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
    cerr << " (Failed)" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
  ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  // We clean up the data
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  char* dataBuf = (char*) msg->pokeArg.data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
  delete[] dataBuf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
  cerr << "Exiting handlePoke()" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
bool
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
suspend() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
  if (suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
  // Before we suspend, we must take a snapshot of the loaded module
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
  // names and base addresses, since acquiring this snapshot requires
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  // starting and exiting a thread in the remote process (at least on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
  // NT 4).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
  libs.clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  cerr << "Starting suspension" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  libInfo(pid, libs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  cerr << "  Got lib info" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  threads.lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  cerr << "  Got thread lock" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  suspended = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  int j = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  for (int i = 0; i < threads.size(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
    j++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
    SuspendThread(threads.get(i).thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  cerr << "Suspended " << j << " threads" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  threads.unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
bool
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
resume() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  threads.lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  suspended = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  for (int i = 0; i < threads.size(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    ResumeThread(threads.get(i).thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
  threads.unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
  cerr << "Resumed process" << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
int
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
main(int argc, char **argv)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  if (argc != 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
    // Should only be used by performing CreateProcess within SwDbgSrv
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
    exit(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  if (sscanf(argv[1], "%u", &pid) != 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
    exit(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  // Try to attach to process
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  if (!attachToProcess()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
    // Attach failed. Notify parent by writing result to stdout file
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
    // handle.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
    char res = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
    DWORD numBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), &res, sizeof(res),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
              &numBytes, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
    exit(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  // Server is expecting success result back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  char res = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
  DWORD numBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), &res, sizeof(res),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
            &numBytes, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  // Initialize our I/O buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  ioBuf = new IOBuf(32768, 131072);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  ioBuf->setOutputFileHandle(GetStdHandle(STD_OUTPUT_HANDLE));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  // At this point we are attached. Enter our main loop which services
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  // requests from the server. Note that in order to handle attach/
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  // detach properly (i.e., resumption of process upon "detach") we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  // will need another thread which handles debug events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  while (true) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
    // Read a message from the server
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    Message msg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    if (!readMessage(&msg)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
      endProcess();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
#ifdef DEBUGGING
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    cerr << "Main thread read message: " << msg.type << endl;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
    switch (msg.type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
    // ATTACH and DETACH messages MUST come in pairs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
    case Message::ATTACH:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
      suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
      eventLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
      generateDebugEvents = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
      eventLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
    case Message::DETACH:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
      eventLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
      generateDebugEvents = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
      // Flush remaining event if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
      if (curDebugEvent != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
        curDebugEvent = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
        eventLock->notifyAll();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
      eventLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
      resume();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
    case Message::LIBINFO:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
        if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
          ioBuf->writeInt(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
          // Send back formatted text
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
          ioBuf->writeInt(libs.size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
          for (int i = 0; i < libs.size(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
            ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
            ioBuf->writeInt(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
            ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
            ioBuf->writeInt(libs[i].name.size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
            ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
            ioBuf->writeString(libs[i].name.c_str());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
            ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
            ioBuf->writeAddress(libs[i].base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
        ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
        ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
    case Message::PEEK:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
      handlePeek(&msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
    case Message::POKE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
      handlePoke(&msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
    case Message::THREADLIST:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
        if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
          ioBuf->writeInt(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
          threads.lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
          ioBuf->writeInt(threads.size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
          for (int i = 0; i < threads.size(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
            ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
            ioBuf->writeAddress((void*) threads.get(i).thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
          threads.unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
        ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
        ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
    case Message::DUPHANDLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
        HANDLE dup;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
        if (DuplicateHandle(procHandle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
                            msg.handleArg.handle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
                            GetCurrentProcess(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
                            &dup,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
                            0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
                            FALSE,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
                            DUPLICATE_SAME_ACCESS)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
          ioBuf->writeBoolAsInt(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
          ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
          ioBuf->writeAddress((void*) dup);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
          ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
        ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
        ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
    case Message::CLOSEHANDLE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
        CloseHandle(msg.handleArg.handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
    case Message::GETCONTEXT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
        if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
          ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
          CONTEXT context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
          context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
          if (GetThreadContext(msg.handleArg.handle, &context)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
            ioBuf->writeBoolAsInt(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
            // EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EIP, DS, ES, FS, GS,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
            // CS, SS, EFLAGS, DR0, DR1, DR2, DR3, DR6, DR7
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
            // See README-commands.txt
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Eax);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Ebx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Ecx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Edx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Esi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Edi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Ebp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Esp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Eip);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegDs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegEs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegFs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegGs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegCs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.SegSs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.EFlags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr6);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
            ioBuf->writeSpace(); ioBuf->writeAddress((void*) context.Dr7);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
            ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
        ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
        ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
    case Message::SETCONTEXT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
        if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
          ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
          CONTEXT context;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
          context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
          context.Eax    = msg.setContextArg.Eax;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
          context.Ebx    = msg.setContextArg.Ebx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
          context.Ecx    = msg.setContextArg.Ecx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
          context.Edx    = msg.setContextArg.Edx;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
          context.Esi    = msg.setContextArg.Esi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
          context.Edi    = msg.setContextArg.Edi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
          context.Ebp    = msg.setContextArg.Ebp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
          context.Esp    = msg.setContextArg.Esp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
          context.Eip    = msg.setContextArg.Eip;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
          context.SegDs  = msg.setContextArg.Ds;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
          context.SegEs  = msg.setContextArg.Es;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
          context.SegFs  = msg.setContextArg.Fs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
          context.SegGs  = msg.setContextArg.Gs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
          context.SegCs  = msg.setContextArg.Cs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
          context.SegSs  = msg.setContextArg.Ss;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
          context.EFlags = msg.setContextArg.EFlags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
          context.Dr0    = msg.setContextArg.Dr0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
          context.Dr1    = msg.setContextArg.Dr1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
          context.Dr2    = msg.setContextArg.Dr2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
          context.Dr3    = msg.setContextArg.Dr3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
          context.Dr6    = msg.setContextArg.Dr6;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
          context.Dr7    = msg.setContextArg.Dr7;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
          if (SetThreadContext(msg.setContextArg.handle, &context)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
            ioBuf->writeBoolAsInt(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
            ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
        ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
        ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
    case Message::SELECTORENTRY:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
        LDT_ENTRY entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
        if (GetThreadSelectorEntry(msg.selectorArg.handle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
                                   msg.selectorArg.selector,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
                                   &entry)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
          ioBuf->writeBoolAsInt(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
          ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.LimitLow);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
          ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.BaseLow);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
          ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.HighWord.Bytes.BaseMid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
          ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.HighWord.Bytes.Flags1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
          ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.HighWord.Bytes.Flags2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
          ioBuf->writeSpace(); ioBuf->writeAddress((void*) entry.HighWord.Bytes.BaseHi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
          ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
        ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
        ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
    case Message::SUSPEND:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
      suspend();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
    case Message::RESUME:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
      resume();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
    case Message::POLLEVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
      eventLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
      if (curDebugEvent == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
        ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
        ioBuf->writeBoolAsInt(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
        ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
        threads.lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
        ioBuf->writeAddress((void*) threads.threadIDToHandle(curDebugEvent->dwThreadId));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
        threads.unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
        ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
        ioBuf->writeUnsignedInt(curDebugEvent->dwDebugEventCode);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
        // Figure out what else to write
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
        switch (curDebugEvent->dwDebugEventCode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
        case LOAD_DLL_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
          ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
          ioBuf->writeAddress(curDebugEvent->u.LoadDll.lpBaseOfDll);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
        case UNLOAD_DLL_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
          ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
          ioBuf->writeAddress(curDebugEvent->u.UnloadDll.lpBaseOfDll);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
        case EXCEPTION_DEBUG_EVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
          {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
            DWORD code = curDebugEvent->u.Exception.ExceptionRecord.ExceptionCode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
            ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
            ioBuf->writeUnsignedInt(code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
            ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
            ioBuf->writeAddress(curDebugEvent->u.Exception.ExceptionRecord.ExceptionAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
            switch (curDebugEvent->u.Exception.ExceptionRecord.ExceptionCode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
            case EXCEPTION_ACCESS_VIOLATION:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
              ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
              ioBuf->writeBoolAsInt(curDebugEvent->u.Exception.ExceptionRecord.ExceptionInformation[0] != 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
              ioBuf->writeSpace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
              ioBuf->writeAddress((void*) curDebugEvent->u.Exception.ExceptionRecord.ExceptionInformation[1]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
              break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
            default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
              break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
        default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
      eventLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
      ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
      ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
    case Message::CONTINUEEVENT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
      eventLock->lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
      if (curDebugEvent == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
        ioBuf->writeBoolAsInt(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
        curDebugEvent = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
        passEventToClient = msg.boolArg.val;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
        ioBuf->writeBoolAsInt(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
        eventLock->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
      eventLock->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
      ioBuf->writeEOL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
      ioBuf->flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  endProcess();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  // NOT REACHED
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
}