hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32DebuggerLocal.java
author coleenp
Sun, 13 Apr 2008 17:43:42 -0400
changeset 360 21d113ecbf6a
parent 1 489c9b5090e2
child 670 ddf3e9583f2f
permissions -rw-r--r--
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
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-2004 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
package sun.jvm.hotspot.debugger.win32;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
import java.io.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
import java.net.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
import java.util.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
import sun.jvm.hotspot.debugger.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
import sun.jvm.hotspot.debugger.x86.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
import sun.jvm.hotspot.debugger.win32.coff.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
import sun.jvm.hotspot.debugger.cdbg.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
import sun.jvm.hotspot.debugger.cdbg.basic.BasicDebugEvent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
import sun.jvm.hotspot.utilities.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
import sun.jvm.hotspot.utilities.memo.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
/** <P> An implementation of the JVMDebugger interface which talks to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
    the Free Windows Debug Server (FwDbgSrv) over a socket to
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
    implement attach/detach and read from process memory. All DLL and
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
    symbol table management is done in Java. </P>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
    <P> <B>NOTE</B> that since we have the notion of fetching "Java
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
    primitive types" from the remote process (which might have
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    different sizes than we expect) we have a bootstrapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
    problem. We need to know the sizes of these types before we can
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
    fetch them. The current implementation solves this problem by
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
    requiring that it be configured with these type sizes before they
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    can be fetched. The readJ(Type) routines here will throw a
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
    RuntimeException if they are called before the debugger is
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
    configured with the Java primitive type sizes. </P> */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
public class Win32DebuggerLocal extends DebuggerBase implements Win32Debugger {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  private Socket debuggerSocket;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  private boolean attached;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  // FIXME: update when core files supported
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  private long pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  // Communication with debug server
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  private PrintWriter out;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  private DataOutputStream rawOut;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  private InputLexer in;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  private static final int PORT = 27000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  private PageCache cache;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  private static final long SHORT_TIMEOUT = 2000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  private static final long LONG_TIMEOUT = 20000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  // Symbol lookup support
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  // This is a map of library names to DLLs
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  private Map nameToDllMap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  // C/C++ debugging support
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  private List/*<LoadObject>*/ loadObjects;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  private CDebugger cdbg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // ProcessControl support
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  private boolean suspended;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  // Maps Long objects (addresses) to Byte objects (original instructions)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  // (Longs used instead of Addresses to properly represent breakpoints at 0x0 if needed)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  private Map     breakpoints;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  // Current debug event, if any
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  private DebugEvent curDebugEvent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  //--------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  // Implementation of Debugger interface
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  /** <P> machDesc may not be null. </P>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
      <P> useCache should be set to true if debugging is being done
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
      locally, and to false if the debugger is being created for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
      purpose of supporting remote debugging. </P> */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  public Win32DebuggerLocal(MachineDescription machDesc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
                            boolean useCache) throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    this.machDesc = machDesc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    utils = new DebuggerUtilities(machDesc.getAddressSize(), machDesc.isBigEndian());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
    if (useCache) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
      // Cache portion of the remote process's address space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
      // Fetching data over the socket connection to dbx is slow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
      // Might be faster if we were using a binary protocol to talk to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
      // dbx, but would have to test. For now, this cache works best
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      // if it covers the entire heap of the remote process. FIXME: at
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
      // least should make this tunable from the outside, i.e., via
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
      // the UI. This is a cache of 4096 4K pages, or 16 MB. The page
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
      // size must be adjusted to be the hardware's page size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
      // (FIXME: should pick this up from the debugger.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
      initCache(4096, parseCacheNumPagesProperty(4096));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
    // FIXME: add instantiation of thread factory
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
      connectToDebugServer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  /** From the Debugger interface via JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  public boolean hasProcessList() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  /** From the Debugger interface via JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  public List getProcessList() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    List processes = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
      printlnToOutput("proclist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
      int num = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
      for (int i = 0; i < num; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
        int pid = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
        String name = parseString();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
        // NOTE: Win32 hack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
        if (name.equals("")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
          name = "System Idle Process";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
        processes.add(new ProcessInfo(name, pid));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
      return processes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  /** From the Debugger interface via JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  public synchronized void attach(int processID) throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    if (attached) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      // FIXME: update when core files supported
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
      throw new DebuggerException("Already attached to process " + pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      printlnToOutput("attach " + processID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
      if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
        throw new DebuggerException("Error attaching to process, or no such process");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
      attached = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
      pid = processID;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
      suspended = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
      breakpoints = new HashMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
      curDebugEvent = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
      nameToDllMap = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
      loadObjects = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
        throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  /** From the Debugger interface via JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  public synchronized void attach(String executableName, String coreFileName) throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    throw new DebuggerException("Core files not yet supported on Win32");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  /** From the Debugger interface via JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  public synchronized boolean detach() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    if (!attached) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    attached = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    suspended = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    breakpoints = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
    // Close all open DLLs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    if (nameToDllMap != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
      for (Iterator iter = nameToDllMap.values().iterator(); iter.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
        DLL dll = (DLL) iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
        dll.close();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
      nameToDllMap = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
      loadObjects = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
    cdbg = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
    clearCache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
      printlnToOutput("detach");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
      return in.parseBoolean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  /** From the Debugger interface via JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  public Address parseAddress(String addressString) throws NumberFormatException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    return newAddress(utils.scanAddress(addressString));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  /** From the Debugger interface via JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  public String getOS() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
    return PlatformInfo.getOS();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
  /** From the Debugger interface via JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  public String getCPU() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
    return PlatformInfo.getCPU();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  public boolean hasConsole() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  public String consoleExecuteCommand(String cmd) throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    throw new DebuggerException("No debugger console available on Win32");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
  public String getConsolePrompt() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
    return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
  public CDebugger getCDebugger() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
    if (cdbg == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
      cdbg = new Win32CDebugger(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
    return cdbg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
  /** From the SymbolLookup interface via Debugger and JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  public synchronized Address lookup(String objectName, String symbol) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
    if (!attached) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
      return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
    return newAddress(lookupInProcess(objectName, symbol));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  /** From the SymbolLookup interface via Debugger and JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  public synchronized OopHandle lookupOop(String objectName, String symbol) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
    Address addr = lookup(objectName, symbol);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
    if (addr == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
      return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
    return addr.addOffsetToAsOopHandle(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  /** From the Debugger interface */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  public MachineDescription getMachineDescription() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    return machDesc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
  //--------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
  // Implementation of ThreadAccess interface
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
  /** From the ThreadAccess interface via Debugger and JVMDebugger */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
  public ThreadProxy getThreadForIdentifierAddress(Address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
    return new Win32Thread(this, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
  public ThreadProxy getThreadForThreadId(long handle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
    return new Win32Thread(this, handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
  //----------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
  // Overridden from DebuggerBase because we need to relax alignment
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
  // constraints on x86
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  public long readJLong(long address)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
    throws UnmappedAddressException, UnalignedAddressException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
    checkJavaConfigured();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
    // FIXME: allow this to be configurable. Undesirable to add a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
    // dependency on the runtime package here, though, since this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
    // package should be strictly underneath it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
    //    utils.checkAlignment(address, jlongSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    utils.checkAlignment(address, jintSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
    byte[] data = readBytes(address, jlongSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    return utils.dataToJLong(data, jlongSize);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  //--------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
  // Internal routines (for implementation of Win32Address).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
  // These must not be called until the MachineDescription has been set up.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
  /** From the Win32Debugger interface */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  public String addressValueToString(long address) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    return utils.addressValueToString(address);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  /** From the Win32Debugger interface */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
  public Win32Address readAddress(long address)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    throws UnmappedAddressException, UnalignedAddressException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
    return (Win32Address) newAddress(readAddressValue(address));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   309
  public Win32Address readCompOopAddress(long address)
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   310
    throws UnmappedAddressException, UnalignedAddressException {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   311
    return (Win32Address) newAddress(readCompOopAddressValue(address));
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   312
  }
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   313
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
  /** From the Win32Debugger interface */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
  public Win32OopHandle readOopHandle(long address)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
    long value = readAddressValue(address);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
    return (value == 0 ? null : new Win32OopHandle(this, value));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
  }
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   320
  public Win32OopHandle readCompOopHandle(long address)
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   321
    throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   322
    long value = readCompOopAddressValue(address);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   323
    return (value == 0 ? null : new Win32OopHandle(this, value));
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   324
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  /** From the Win32Debugger interface */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  public void writeAddress(long address, Win32Address value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
    writeAddressValue(address, getAddressValue(value));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  /** From the Win32Debugger interface */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  public void writeOopHandle(long address, Win32OopHandle value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
    writeAddressValue(address, getAddressValue(value));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  //--------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  // Thread context access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  public synchronized long[] getThreadIntegerRegisterSet(int threadHandleValue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
                                                         boolean mustDuplicateHandle)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
    throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
      throw new DebuggerException("Process not suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
      int handle = threadHandleValue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
      if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
        printlnToOutput("duphandle 0x" + Integer.toHexString(threadHandleValue));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
        if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
          throw new DebuggerException("Error duplicating thread handle 0x" + threadHandleValue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
        handle = (int) in.parseAddress(); // Must close to avoid leaks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
      printlnToOutput("getcontext 0x" + Integer.toHexString(handle));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
      if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
        if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
          printlnToOutput("closehandle 0x" + Integer.toHexString(handle));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
        String failMessage = "GetThreadContext failed for thread handle 0x" +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
                             Integer.toHexString(handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
        if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
          failMessage = failMessage + ", duplicated from thread handle " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
                        Integer.toHexString(threadHandleValue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
        throw new DebuggerException(failMessage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
      // Otherwise, parse all registers. See
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
      // src/os/win32/agent/README-commands.txt for the format.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
      // Note the array we have to return has to match that specified by
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
      // X86ThreadContext.java.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
      int numRegs = 22;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
      long[] winRegs = new long[numRegs];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
      for (int i = 0; i < numRegs; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
        winRegs[i] = in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
      if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
        // Clean up after ourselves
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
        printlnToOutput("closehandle 0x" + Integer.toHexString(handle));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
      // Now create the real return value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
      long[] retval = new long[X86ThreadContext.NPRGREG];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
      retval[X86ThreadContext.EAX] = winRegs[0];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
      retval[X86ThreadContext.EBX] = winRegs[1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
      retval[X86ThreadContext.ECX] = winRegs[2];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
      retval[X86ThreadContext.EDX] = winRegs[3];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
      retval[X86ThreadContext.ESI] = winRegs[4];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
      retval[X86ThreadContext.EDI] = winRegs[5];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
      retval[X86ThreadContext.EBP] = winRegs[6];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
      retval[X86ThreadContext.ESP] = winRegs[7];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
      retval[X86ThreadContext.EIP] = winRegs[8];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
      retval[X86ThreadContext.DS]  = winRegs[9];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
      retval[X86ThreadContext.ES]  = winRegs[10];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
      retval[X86ThreadContext.FS]  = winRegs[11];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
      retval[X86ThreadContext.GS]  = winRegs[12];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
      retval[X86ThreadContext.CS]  = winRegs[13];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
      retval[X86ThreadContext.SS]  = winRegs[14];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
      retval[X86ThreadContext.EFL] = winRegs[15];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
      retval[X86ThreadContext.DR0] = winRegs[16];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
      retval[X86ThreadContext.DR1] = winRegs[17];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
      retval[X86ThreadContext.DR2] = winRegs[18];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
      retval[X86ThreadContext.DR3] = winRegs[19];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
      retval[X86ThreadContext.DR6] = winRegs[20];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
      retval[X86ThreadContext.DR7] = winRegs[21];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
      return retval;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  public synchronized void setThreadIntegerRegisterSet(int threadHandleValue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
                                                       boolean mustDuplicateHandle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
                                                       long[] context)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
    if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
      throw new DebuggerException("Process not suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
      int handle = threadHandleValue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
      if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
        printlnToOutput("duphandle 0x" + Integer.toHexString(threadHandleValue));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
        if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
          throw new DebuggerException("Error duplicating thread handle 0x" + threadHandleValue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
        handle = (int) in.parseAddress(); // Must close to avoid leaks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
      // Change order of registers to match that of debug server
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
      long[] winRegs = new long[context.length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
      winRegs[0] = context[X86ThreadContext.EAX];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
      winRegs[1] = context[X86ThreadContext.EBX];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
      winRegs[2] = context[X86ThreadContext.ECX];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
      winRegs[3] = context[X86ThreadContext.EDX];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
      winRegs[4] = context[X86ThreadContext.ESI];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
      winRegs[5] = context[X86ThreadContext.EDI];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
      winRegs[6] = context[X86ThreadContext.EBP];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
      winRegs[7] = context[X86ThreadContext.ESP];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
      winRegs[8] = context[X86ThreadContext.EIP];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
      winRegs[9] = context[X86ThreadContext.DS];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
      winRegs[10] = context[X86ThreadContext.ES];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
      winRegs[11] = context[X86ThreadContext.FS];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
      winRegs[12] = context[X86ThreadContext.GS];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
      winRegs[13] = context[X86ThreadContext.CS];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
      winRegs[14] = context[X86ThreadContext.SS];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
      winRegs[15] = context[X86ThreadContext.EFL];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
      winRegs[16] = context[X86ThreadContext.DR0];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
      winRegs[17] = context[X86ThreadContext.DR1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
      winRegs[18] = context[X86ThreadContext.DR2];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
      winRegs[19] = context[X86ThreadContext.DR3];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
      winRegs[20] = context[X86ThreadContext.DR6];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
      winRegs[21] = context[X86ThreadContext.DR7];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
      StringBuffer cmd = new StringBuffer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
      cmd.append("setcontext 0x");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
      cmd.append(Integer.toHexString(threadHandleValue));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
      for (int i = 0; i < context.length; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
        cmd.append(" 0x");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
        cmd.append(Long.toHexString(winRegs[i]));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
      printlnToOutput(cmd.toString());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
      boolean res = in.parseBoolean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
      if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
        printlnToOutput("closehandle 0x" + Integer.toHexString(handle));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
      if (!res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
        String failMessage = "SetThreadContext failed for thread handle 0x" +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
          Integer.toHexString(handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
        if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
          failMessage = failMessage + ", duplicated from thread handle " +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
            Integer.toHexString(threadHandleValue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
        throw new DebuggerException(failMessage);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  /** Fetches the Win32 LDT_ENTRY for the given thread and selector.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
      This data structure allows the conversion of a segment-relative
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
      address to a linear virtual address. For example, it allows the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
      expression of operations like "mov eax, fs:[18h]", which fetches
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
      the thread information block, allowing access to the thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
      ID. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  public synchronized Win32LDTEntry getThreadSelectorEntry(int threadHandleValue,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
                                                           boolean mustDuplicateHandle,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
                                                           int selector)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
    throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
      int handle = threadHandleValue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
      if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
        printlnToOutput("duphandle 0x" + Integer.toHexString(threadHandleValue));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
        if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
          throw new DebuggerException("Error duplicating thread handle 0x" + threadHandleValue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
        handle = (int) in.parseAddress(); // Must close to avoid leaks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
      printlnToOutput("selectorentry 0x" + Integer.toHexString(handle) + " " + selector);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
      if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
        if (mustDuplicateHandle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
          printlnToOutput("closehandle 0x" + Integer.toHexString(handle));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
        throw new DebuggerException("GetThreadContext failed for thread handle 0x" + handle +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
                                    ", duplicated from thread handle " + threadHandleValue);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
      // Parse result. See
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
      // src/os/win32/agent/README-commands.txt for the format.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
      short limitLow = (short) in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
      short baseLow  = (short) in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
      byte  baseMid  = (byte)  in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
      byte  flags1   = (byte)  in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
      byte  flags2   = (byte)  in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
      byte  baseHi   = (byte)  in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
      return new Win32LDTEntry(limitLow, baseLow, baseMid, flags1, flags2, baseHi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  public synchronized List getThreadList() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
    if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
      throw new DebuggerException("Process not suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
      printlnToOutput("threadlist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
      List ret = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
      int numThreads = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
      for (int i = 0; i < numThreads; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
        int handle = (int) in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
        ret.add(new Win32Thread(this, handle));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
      return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
  public synchronized List getLoadObjectList() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
    if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      throw new DebuggerException("Process not suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
      if (loadObjects == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
        loadObjects  = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
        nameToDllMap = new HashMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
        // Get list of library names and base addresses
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
        printlnToOutput("libinfo");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
        int numInfo = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
        for (int i = 0; i < numInfo; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
          // NOTE: because Win32 is case insensitive, we standardize on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
          // lowercase file names.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
          String  fullPathName = parseString().toLowerCase();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
          Address base         = newAddress(in.parseAddress());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
          File   file = new File(fullPathName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
          long   size = file.length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
          DLL    dll  = new DLL(this, fullPathName, size, base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
          String name = file.getName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
          nameToDllMap.put(name, dll);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
          loadObjects.add(dll);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
    return loadObjects;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  //----------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
  // Process control access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  public synchronized void writeBytesToProcess(long startAddress, long numBytes, byte[] data)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
    throws UnmappedAddressException, DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
      printToOutput("poke 0x" + Long.toHexString(startAddress) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
                    " |");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
      writeIntToOutput((int) numBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
      writeToOutput(data, 0, (int) numBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
      printlnToOutput("");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
      if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
        throw new UnmappedAddressException(startAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  public synchronized void suspend() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
      if (suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
        throw new DebuggerException("Process already suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
      printlnToOutput("suspend");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
      suspended = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
      enableCache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
      reresolveLoadObjects();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
  public synchronized void resume() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
      if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
        throw new DebuggerException("Process not suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
      disableCache();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
      printlnToOutput("resume");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
      suspended = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
  public synchronized boolean isSuspended() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
    return suspended;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  public synchronized void setBreakpoint(Address addr) throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
    if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
      throw new DebuggerException("Process not suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
    long addrVal = getAddressValue(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
    Long where = new Long(addrVal);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
    if (breakpoints.get(where) != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
      throw new DebuggerException("Breakpoint already set at " + addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
    Byte what = new Byte(readBytes(addrVal, 1)[0]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
    // Now put 0xCC (int 3) at the target address, fail if can not
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    writeBytesToProcess(addrVal, 1, new byte[] { (byte) 0xCC });
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
    // OK, the breakpoint is set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
    breakpoints.put(where, what);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
  public synchronized void clearBreakpoint(Address addr) throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
    if (!suspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
      throw new DebuggerException("Process not suspended");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
    long addrVal = getAddressValue(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
    Long where = new Long(addrVal);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
    Byte what = (Byte) breakpoints.get(where);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
    if (what == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
      throw new DebuggerException("Breakpoint not set at " + addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    // Put original data back at address
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    writeBytesToProcess(addrVal, 1, new byte[] { what.byteValue() });
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    // OK, breakpoint is cleared
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
    breakpoints.remove(where);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
  public synchronized boolean isBreakpointSet(Address addr) throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
    return (breakpoints.get(new Long(getAddressValue(addr))) != null);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
  // Following constants taken from winnt.h
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
  private static final int EXCEPTION_DEBUG_EVENT  = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
  private static final int LOAD_DLL_DEBUG_EVENT   = 6;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  private static final int UNLOAD_DLL_DEBUG_EVENT = 7;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
  private static final int EXCEPTION_ACCESS_VIOLATION = 0xC0000005;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
  private static final int EXCEPTION_BREAKPOINT       = 0x80000003;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
  private static final int EXCEPTION_SINGLE_STEP      = 0x80000004;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
  public synchronized DebugEvent debugEventPoll() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
    if (curDebugEvent != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
      return curDebugEvent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
      printlnToOutput("pollevent");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
      if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
        return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
      // Otherwise, got a debug event. Need to figure out what kind it is.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
      int handle = (int) in.parseAddress();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
      ThreadProxy thread = new Win32Thread(this, handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
      int code = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
      DebugEvent ev = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
      switch (code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
      case LOAD_DLL_DEBUG_EVENT: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
        Address addr = newAddress(in.parseAddress());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
        ev = BasicDebugEvent.newLoadObjectLoadEvent(thread, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
      case UNLOAD_DLL_DEBUG_EVENT: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
        Address addr = newAddress(in.parseAddress());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
        ev = BasicDebugEvent.newLoadObjectUnloadEvent(thread, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
      case EXCEPTION_DEBUG_EVENT: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
        int exceptionCode = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
        Address pc = newAddress(in.parseAddress());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
        switch (exceptionCode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
        case EXCEPTION_ACCESS_VIOLATION:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
          boolean wasWrite = in.parseBoolean();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
          Address addr = newAddress(in.parseAddress());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
          ev = BasicDebugEvent.newAccessViolationEvent(thread, pc, wasWrite, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
        case EXCEPTION_BREAKPOINT:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
          ev = BasicDebugEvent.newBreakpointEvent(thread, pc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
        case EXCEPTION_SINGLE_STEP:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
          ev = BasicDebugEvent.newSingleStepEvent(thread, pc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
        default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
          ev = BasicDebugEvent.newUnknownEvent(thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
                                               "Exception 0x" + Integer.toHexString(exceptionCode) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
                                               " at PC " + pc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
      default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
        ev = BasicDebugEvent.newUnknownEvent(thread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
                                             "Debug event " + code + " occurred");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
      if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
        Assert.that(ev != null, "Must have created event");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
      curDebugEvent = ev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
    return curDebugEvent;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
  public synchronized void debugEventContinue() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
    if (curDebugEvent == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
      throw new DebuggerException("No debug event pending");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
      ///////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
      //                                                               //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
      // FIXME: this **must** be modified to handle breakpoint events
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
      // properly. Must temporarily remove the breakpoint and enable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
      // single-stepping mode (hiding those single-step events from
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
      // the user unless they have been requested; currently there is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
      // no way to request single-step events; and it isn't clear how
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
      // to enable them or how the hardware and/or OS typically
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
      // supports them, i.e., are they on a per-process or per-thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
      // level?) until the process steps past the breakpoint, then put
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
      // the breakpoint back.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
      //                                                               //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
      ///////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
      DebugEvent.Type t = curDebugEvent.getType();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
      boolean shouldPassOn = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
      if (t == DebugEvent.Type.BREAKPOINT) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
        // FIXME: correct algorithm appears to be as follows:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
        // 1. Check to see whether we know about this breakpoint. If
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
        // not, it's requested by the user's program and we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
        // ignore it (not pass it on to the program).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
        // 2. Replace the original opcode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
        // 3. Set single-stepping mode in the debug registers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
        // 4. Back up the PC.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
        // 5. In debugEventPoll(), watch for a single-step event on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
        // this thread. When we get it, put the breakpoint back. Only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
        // deliver that single-step event if the user has requested
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
        // single-step events (FIXME: must figure out whether they are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
        // per-thread or per-process, and also expose a way to turn
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
        // them on.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
        // To make breakpoints work for now, we will just back up the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
        // PC, which we have to do in order to not disrupt the program
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
        // execution in case the user decides to disable the breakpoint.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
        if (breakpoints.get(new Long(getAddressValue(curDebugEvent.getPC()))) != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
          System.err.println("Backing up PC due to breakpoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
          X86ThreadContext ctx = (X86ThreadContext) curDebugEvent.getThread().getContext();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
          ctx.setRegister(X86ThreadContext.EIP, ctx.getRegister(X86ThreadContext.EIP) - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
          curDebugEvent.getThread().setContext(ctx);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
          System.err.println("Skipping back up of PC since I didn't know about this breakpoint");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
          System.err.println("Known breakpoints:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
          for (Iterator iter = breakpoints.keySet().iterator(); iter.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
            System.err.println("  0x" + Long.toHexString(((Long) iter.next()).longValue()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
        shouldPassOn = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
      } else if (t == DebugEvent.Type.SINGLE_STEP) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
        shouldPassOn = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
      // Other kinds of debug events are either ignored if passed on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
      // or probably should be passed on so the program exits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
      // FIXME: generate process exiting events (should be easy)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
      int val = (shouldPassOn ? 1 : 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
      printlnToOutput("continueevent " + val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
      if (!in.parseBoolean()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
        throw new DebuggerException("Unknown error while attempting to continue past debug event");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
      curDebugEvent = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
  //--------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
  // Address access
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
  /** From the Debugger interface */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
  public long getAddressValue(Address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
    if (addr == null) return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
    return ((Win32Address) addr).getValue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
  /** From the Win32Debugger interface */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
  public Address newAddress(long value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
    if (value == 0) return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
    return new Win32Address(this, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
  //--------------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
  // Internals only below this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
  private String parseString() throws IOException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
    int charSize = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
    int numChars = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
    in.skipByte();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
    String str;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
    if (charSize == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
      str = in.readByteString(numChars);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
      str = in.readCharString(numChars);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
    return str;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
  /** Looks up an address in the remote process's address space.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
      Returns 0 if symbol not found or upon error. Package private to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
      allow Win32DebuggerRemoteIntfImpl access. NOTE that this returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
      a long instead of an Address because we do not want to serialize
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
      Addresses. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
  synchronized long lookupInProcess(String objectName, String symbol) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
    // NOTE: this assumes that process is suspended (which is probably
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
    // necessary assumption given that DLLs can be loaded/unloaded as
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
    // process runs). Should update documentation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
    if (nameToDllMap == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
      getLoadObjectList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
    DLL dll = (DLL) nameToDllMap.get(objectName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
    // The DLL can be null because we use this to search through known
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
    // DLLs in HotSpotTypeDataBase (for example)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
    if (dll != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
      Win32Address addr = (Win32Address) dll.lookupSymbol(symbol);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
      if (addr != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
        return addr.getValue();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
    return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  /** This reads bytes from the remote process. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
  public synchronized ReadResult readBytesFromProcess(long address, long numBytes)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
    throws UnmappedAddressException, DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
      String cmd = "peek " + utils.addressValueToString(address) + " " + numBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
      printlnToOutput(cmd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
      while (in.readByte() != 'B') {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
      byte res = in.readByte();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
      if (res == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
        System.err.println("Failing command: " + cmd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
        throw new DebuggerException("Read of remote process address space failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
      // NOTE: must read ALL of the data regardless of whether we need
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
      // to throw an UnmappedAddressException. Otherwise will corrupt
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
      // the input stream each time we have a failure. Not good. Do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
      // not want to risk "flushing" the input stream in case a huge
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
      // read has a hangup in the middle and we leave data on the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
      // stream.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
      byte[] buf = new byte[(int) numBytes];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
      boolean bailOut = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
      long failureAddress = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
      while (numBytes > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
        long len = in.readUnsignedInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
        boolean isMapped = ((in.readByte() == 0) ? false : true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
        if (!isMapped) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
          if (!bailOut) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
            bailOut = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
            failureAddress = address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
          // This won't work if we have unmapped regions, but if we do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
          // then we're going to throw an exception anyway
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
          // NOTE: there is a factor of 20 speed difference between
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
          // these two ways of doing this read.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
          in.readBytes(buf, 0, (int) len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
        // Do NOT do this:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
        //        for (int i = 0; i < (int) len; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
        //          buf[i] = in.readByte();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
        //        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
        numBytes -= len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
        address += len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
      if (Assert.ASSERTS_ENABLED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
        Assert.that(numBytes == 0, "Bug in debug server's implementation of peek");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
      if (bailOut) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
        return new ReadResult(failureAddress);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
      return new ReadResult(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
    catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
  /** Convenience routines */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
  private void printlnToOutput(String s) throws IOException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
    out.println(s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
    if (out.checkError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
      throw new IOException("Error occurred while writing to debug server");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
  private void printToOutput(String s) throws IOException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
    out.print(s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
    if (out.checkError()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
      throw new IOException("Error occurred while writing to debug server");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
  private void writeIntToOutput(int val) throws IOException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
    rawOut.writeInt(val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    rawOut.flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
  private void writeToOutput(byte[] buf, int off, int len) throws IOException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
    rawOut.write(buf, off, len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
    rawOut.flush();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
  /** Connects to the debug server, setting up out and in streams. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  private void connectToDebugServer() throws IOException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
    // Try for a short period of time to connect to debug server; time out
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
    // with failure if didn't succeed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
    debuggerSocket = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
    long endTime = System.currentTimeMillis() + SHORT_TIMEOUT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
    while ((debuggerSocket == null) && (System.currentTimeMillis() < endTime)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
      try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
        // FIXME: this does not work if we are on a DHCP machine which
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
        // did not get an IP address this session. It appears to use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
        // an old cached address and the connection does not actually
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
        // succeed. Must file a bug.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
        // debuggerSocket = new Socket(InetAddress.getLocalHost(), PORT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
        debuggerSocket = new Socket(InetAddress.getByName("127.0.0.1"), PORT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
        debuggerSocket.setTcpNoDelay(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
      catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
        // Swallow IO exceptions while attempting connection
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
        debuggerSocket = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
        try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
          // Don't swamp the CPU
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
          Thread.sleep(750);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
        catch (InterruptedException ex) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
    if (debuggerSocket == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
      // Failed to connect because of timeout
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
      throw new DebuggerException("Timed out while attempting to connect to debug server (please start SwDbgSrv.exe)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
    out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(debuggerSocket.getOutputStream(), "US-ASCII")), true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
    rawOut = new DataOutputStream(new BufferedOutputStream(debuggerSocket.getOutputStream()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
    in = new InputLexer(new BufferedInputStream(debuggerSocket.getInputStream()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  private DLL findDLLByName(String fullPathName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
    for (Iterator iter = loadObjects.iterator(); iter.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
      DLL dll = (DLL) iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
      if (dll.getName().equals(fullPathName)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
        return dll;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
    return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
  private void reresolveLoadObjects() throws DebuggerException {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
    try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
      // It is too expensive to throw away the loadobject list every
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
      // time the process is suspended, largely because of debug
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
      // information re-parsing. When we suspend the target process we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
      // instead fetch the list of loaded libraries in the target and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
      // see whether any loadobject needs to be thrown away (because it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
      // was unloaded) or invalidated (because it was unloaded and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
      // reloaded at a different target address). Note that we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
      // properly handle the case of a loaded DLL being unloaded,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
      // recompiled, and reloaded. We could handle this by keeping a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
      // time stamp.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
      if (loadObjects == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
      // Need to create new list since have to figure out which ones
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
      // were unloaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
      List newLoadObjects = new ArrayList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
    // Get list of library names and base addresses
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
      printlnToOutput("libinfo");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
      int numInfo = in.parseInt();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
      for (int i = 0; i < numInfo; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
        // NOTE: because Win32 is case insensitive, we standardize on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
        // lowercase file names.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
        String  fullPathName = parseString().toLowerCase();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
        Address base         = newAddress(in.parseAddress());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
        // Look for full path name in DLL list
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
        DLL dll = findDLLByName(fullPathName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
        boolean mustLoad = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
        if (dll != null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
          loadObjects.remove(dll);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
          // See whether base addresses match; otherwise, need to reload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
          if (AddressOps.equal(base, dll.getBase())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
            mustLoad = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
        if (mustLoad) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
          // Create new DLL
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
          File   file = new File(fullPathName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
          long   size = file.length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
          String name = file.getName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
          dll  = new DLL(this, fullPathName, size, base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
          nameToDllMap.put(name, dll);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
        newLoadObjects.add(dll);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
      // All remaining entries in loadObjects have to be removed from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
      // the nameToDllMap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
      for (Iterator dllIter = loadObjects.iterator(); dllIter.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
        DLL dll = (DLL) dllIter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
        for (Iterator iter = nameToDllMap.keySet().iterator(); iter.hasNext(); ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
          String name = (String) iter.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
          if (nameToDllMap.get(name) == dll) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
            nameToDllMap.remove(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
      loadObjects = newLoadObjects;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
    } catch (IOException e) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
      loadObjects = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
      nameToDllMap = null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
      throw new DebuggerException(e);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
}