agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot-8003348 Sdiff agent/src/share/classes/sun/jvm/hotspot/debugger/bsd

agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java

Print this page
8003348: SA can not read core file on OS X
   1 /*
   2  * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.debugger.bsd;
  26 
  27 import java.io.*;
  28 import java.net.*;
  29 import java.util.*;
  30 import sun.jvm.hotspot.debugger.*;
  31 import sun.jvm.hotspot.debugger.x86.*;
  32 import sun.jvm.hotspot.debugger.cdbg.*;
  33 import sun.jvm.hotspot.utilities.*;



  34 import java.lang.reflect.*;
  35 
  36 /** <P> An implementation of the JVMDebugger interface. The basic debug
  37     facilities are implemented through ptrace interface in the JNI code
  38     (libsaproc.so). Library maps and symbol table management are done in
  39     JNI. </P>
  40 
  41     <P> <B>NOTE</B> that since we have the notion of fetching "Java
  42     primitive types" from the remote process (which might have
  43     different sizes than we expect) we have a bootstrapping
  44     problem. We need to know the sizes of these types before we can
  45     fetch them. The current implementation solves this problem by
  46     requiring that it be configured with these type sizes before they
  47     can be fetched. The readJ(Type) routines here will throw a
  48     RuntimeException if they are called before the debugger is
  49     configured with the Java primitive type sizes. </P> */
  50 
  51 public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
  52     private boolean useGCC32ABI;
  53     private boolean attached;
  54     private long    p_ps_prochandle; // native debugger handle
  55     private long    symbolicator; // macosx symbolicator handle
  56     private long    task; // macosx task handle
  57     private boolean isCore;

  58 
  59     // CDebugger support
  60     private BsdCDebugger cdbg;
  61 
  62     // threadList and loadObjectList are filled by attach0 method
  63     private List threadList;
  64     private List loadObjectList;
  65 
  66     // called by native method lookupByAddress0
  67     private ClosestSymbol createClosestSymbol(String name, long offset) {
  68        return new ClosestSymbol(name, offset);
  69     }
  70 
  71     // called by native method attach0
  72     private LoadObject createLoadObject(String fileName, long textsize,
  73                                         long base) {
  74        File f = new File(fileName);
  75        Address baseAddr = newAddress(base);
  76        return new SharedObject(this, fileName, f.length(), baseAddr);
  77     }


 191 
 192         if (useCache) {
 193             // FIXME: re-test necessity of cache on Bsd, where data
 194             // fetching is faster
 195             // Cache portion of the remote process's address space.
 196             // Fetching data over the socket connection to dbx is slow.
 197             // Might be faster if we were using a binary protocol to talk to
 198             // dbx, but would have to test. For now, this cache works best
 199             // if it covers the entire heap of the remote process. FIXME: at
 200             // least should make this tunable from the outside, i.e., via
 201             // the UI. This is a cache of 4096 4K pages, or 16 MB. The page
 202             // size must be adjusted to be the hardware's page size.
 203             // (FIXME: should pick this up from the debugger.)
 204             if (getCPU().equals("ia64")) {
 205               initCache(16384, parseCacheNumPagesProperty(1024));
 206             } else {
 207               initCache(4096, parseCacheNumPagesProperty(4096));
 208             }
 209         }
 210 

 211         workerThread = new BsdDebuggerLocalWorkerThread(this);
 212         workerThread.start();
 213     }
 214 
 215     /** From the Debugger interface via JVMDebugger */
 216     public boolean hasProcessList() throws DebuggerException {
 217         return false;
 218     }
 219 
 220     /** From the Debugger interface via JVMDebugger */
 221     public List getProcessList() throws DebuggerException {
 222         throw new DebuggerException("getProcessList not implemented yet");
 223     }
 224 
 225     private void checkAttached() throws DebuggerException {
 226         if (attached) {
 227             if (isCore) {
 228                 throw new DebuggerException("attached to a core dump already");
 229             } else {
 230                 throw new DebuggerException("attached to a process already");
 231             }
 232         }
 233     }
 234 
 235     private void requireAttach() {
 236         if (! attached) {
 237             throw new RuntimeException("not attached to a process or a core!");
 238         }
 239     }
 240 
 241     /* called from attach methods */
 242     private void findABIVersion() throws DebuggerException {
 243         if (lookupByName0("libjvm.so", "__vt_10JavaThread") != 0 ||
 244             lookupByName0("libjvm_g.so", "__vt_10JavaThread") != 0) {



 245             // old C++ ABI
 246             useGCC32ABI = false;
 247         } else {
 248             // new C++ ABI
 249             useGCC32ABI = true;
 250         }
 251     }
 252 
 253     /** From the Debugger interface via JVMDebugger */
 254     public synchronized void attach(int processID) throws DebuggerException {
 255         checkAttached();
 256         threadList = new ArrayList();
 257         loadObjectList = new ArrayList();
 258         class AttachTask implements WorkerThreadTask {
 259            int pid;
 260            public void doit(BsdDebuggerLocal debugger) {
 261               debugger.attach0(pid);
 262               debugger.attached = true;
 263               debugger.isCore = false;
 264               findABIVersion();


 343         return null;
 344     }
 345 
 346     /* called from lookup */
 347     private long handleGCC32ABI(long addr, String symbol) throws DebuggerException {
 348         if (useGCC32ABI && symbol.startsWith("_ZTV")) {
 349             return addr + (2 * machDesc.getAddressSize());
 350         } else {
 351             return addr;
 352         }
 353     }
 354 
 355     /** From the SymbolLookup interface via Debugger and JVMDebugger */
 356     public synchronized Address lookup(String objectName, String symbol) {
 357         requireAttach();
 358         if (!attached) {
 359             return null;
 360         }
 361 
 362         if (isCore) {
 363             long addr = lookupByName0(objectName, symbol);

 364             return (addr == 0)? null : new BsdAddress(this, handleGCC32ABI(addr, symbol));
 365         } else {
 366             class LookupByNameTask implements WorkerThreadTask {
 367                 String objectName, symbol;
 368                 Address result;
 369 
 370                 public void doit(BsdDebuggerLocal debugger) {
 371                     long addr = debugger.lookupByName0(objectName, symbol);
 372                     result = (addr == 0 ? null : new BsdAddress(debugger, handleGCC32ABI(addr, symbol)));
 373                 }
 374             }
 375 
 376             LookupByNameTask task = new LookupByNameTask();
 377             task.objectName = objectName;
 378             task.symbol = symbol;
 379             workerThread.execute(task);
 380             return task.result;
 381         }
 382     }
 383 


 386         Address addr = lookup(objectName, symbol);
 387         if (addr == null) {
 388             return null;
 389         }
 390         return addr.addOffsetToAsOopHandle(0);
 391     }
 392 
 393     /** From the Debugger interface */
 394     public MachineDescription getMachineDescription() {
 395         return machDesc;
 396     }
 397 
 398     //----------------------------------------------------------------------
 399     // Implementation of ThreadAccess interface
 400     //
 401 
 402     /** From the ThreadAccess interface via Debugger and JVMDebugger */
 403     public ThreadProxy getThreadForIdentifierAddress(Address threadIdAddr, Address uniqueThreadIdAddr) {
 404         return new BsdThread(this, threadIdAddr, uniqueThreadIdAddr);
 405     }

 406     @Override
 407     public ThreadProxy getThreadForIdentifierAddress(Address addr) {
 408         throw new RuntimeException("unimplemented");
 409     }
 410 
 411 
 412     /** From the ThreadAccess interface via Debugger and JVMDebugger */
 413     public ThreadProxy getThreadForThreadId(long id) {
 414         return new BsdThread(this, id);
 415     }
 416 
 417     //----------------------------------------------------------------------
 418     // Internal routines (for implementation of BsdAddress).
 419     // These must not be called until the MachineDescription has been set up.
 420     //
 421 
 422     /** From the BsdDebugger interface */
 423     public String addressValueToString(long address) {
 424         return utils.addressValueToString(address);
 425     }
 426 
 427     /** From the BsdDebugger interface */
 428     public BsdAddress readAddress(long address)
 429             throws UnmappedAddressException, UnalignedAddressException {
 430         long value = readAddressValue(address);
 431         return (value == 0 ? null : new BsdAddress(this, value));


 584                         result = new ReadResult(res);
 585                     else
 586                         result = new ReadResult(address);
 587                 }
 588             }
 589 
 590             ReadBytesFromProcessTask task = new ReadBytesFromProcessTask();
 591             task.address = address;
 592             task.numBytes = numBytes;
 593             workerThread.execute(task);
 594             return task.result;
 595         }
 596     }
 597 
 598     public void writeBytesToProcess(long address, long numBytes, byte[] data)
 599         throws UnmappedAddressException, DebuggerException {
 600         // FIXME
 601         throw new DebuggerException("Unimplemented");
 602     }
 603 



























 604     static {
 605         System.loadLibrary("saproc");
 606         init0();
 607     }
 608 }
   1 /*
   2  * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.debugger.bsd;
  26 
  27 import java.io.*;
  28 import java.net.*;
  29 import java.util.*;
  30 import sun.jvm.hotspot.debugger.*;
  31 import sun.jvm.hotspot.debugger.x86.*;
  32 import sun.jvm.hotspot.debugger.cdbg.*;
  33 import sun.jvm.hotspot.utilities.*;
  34 import sun.jvm.hotspot.runtime.VM;
  35 import sun.jvm.hotspot.runtime.Threads;
  36 import sun.jvm.hotspot.runtime.JavaThread;
  37 import java.lang.reflect.*;
  38 
  39 /** <P> An implementation of the JVMDebugger interface. The basic debug
  40     facilities are implemented through ptrace interface in the JNI code
  41     (libsaproc.so). Library maps and symbol table management are done in
  42     JNI. </P>
  43 
  44     <P> <B>NOTE</B> that since we have the notion of fetching "Java
  45     primitive types" from the remote process (which might have
  46     different sizes than we expect) we have a bootstrapping
  47     problem. We need to know the sizes of these types before we can
  48     fetch them. The current implementation solves this problem by
  49     requiring that it be configured with these type sizes before they
  50     can be fetched. The readJ(Type) routines here will throw a
  51     RuntimeException if they are called before the debugger is
  52     configured with the Java primitive type sizes. </P> */
  53 
  54 public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
  55     private boolean useGCC32ABI;
  56     private boolean attached;
  57     private long    p_ps_prochandle;      // native debugger handle
  58     private long    symbolicator;         // macosx symbolicator handle
  59     private long    task;                 // macosx task handle
  60     private boolean isCore;
  61     private boolean isDarwin;             // variant for bsd
  62 
  63     // CDebugger support
  64     private BsdCDebugger cdbg;
  65 
  66     // threadList and loadObjectList are filled by attach0 method
  67     private List threadList;
  68     private List loadObjectList;
  69 
  70     // called by native method lookupByAddress0
  71     private ClosestSymbol createClosestSymbol(String name, long offset) {
  72        return new ClosestSymbol(name, offset);
  73     }
  74 
  75     // called by native method attach0
  76     private LoadObject createLoadObject(String fileName, long textsize,
  77                                         long base) {
  78        File f = new File(fileName);
  79        Address baseAddr = newAddress(base);
  80        return new SharedObject(this, fileName, f.length(), baseAddr);
  81     }


 195 
 196         if (useCache) {
 197             // FIXME: re-test necessity of cache on Bsd, where data
 198             // fetching is faster
 199             // Cache portion of the remote process's address space.
 200             // Fetching data over the socket connection to dbx is slow.
 201             // Might be faster if we were using a binary protocol to talk to
 202             // dbx, but would have to test. For now, this cache works best
 203             // if it covers the entire heap of the remote process. FIXME: at
 204             // least should make this tunable from the outside, i.e., via
 205             // the UI. This is a cache of 4096 4K pages, or 16 MB. The page
 206             // size must be adjusted to be the hardware's page size.
 207             // (FIXME: should pick this up from the debugger.)
 208             if (getCPU().equals("ia64")) {
 209               initCache(16384, parseCacheNumPagesProperty(1024));
 210             } else {
 211               initCache(4096, parseCacheNumPagesProperty(4096));
 212             }
 213         }
 214 
 215         isDarwin = getOS().equals("darwin");
 216         workerThread = new BsdDebuggerLocalWorkerThread(this);
 217         workerThread.start();
 218     }
 219 
 220     /** From the Debugger interface via JVMDebugger */
 221     public boolean hasProcessList() throws DebuggerException {
 222         return false;
 223     }
 224 
 225     /** From the Debugger interface via JVMDebugger */
 226     public List getProcessList() throws DebuggerException {
 227         throw new DebuggerException("getProcessList not implemented yet");
 228     }
 229 
 230     private void checkAttached() throws DebuggerException {
 231         if (attached) {
 232             if (isCore) {
 233                 throw new DebuggerException("attached to a core dump already");
 234             } else {
 235                 throw new DebuggerException("attached to a process already");
 236             }
 237         }
 238     }
 239 
 240     private void requireAttach() {
 241         if (! attached) {
 242             throw new RuntimeException("not attached to a process or a core!");
 243         }
 244     }
 245 
 246     /* called from attach methods */
 247     private void findABIVersion() throws DebuggerException {
 248         String libjvmName = isDarwin ? "libjvm.dylib" : "libjvm.so";
 249         String libjvm_gName = isDarwin? "libjvm_g.dylib" : "libjvm_g.so";
 250         String javaThreadVt = isDarwin ? "_vt_10JavaThread" : "__vt_10JavaThread";
 251         if (lookupByName0(libjvmName, javaThreadVt) != 0 ||
 252             lookupByName0(libjvm_gName, javaThreadVt) != 0) {
 253             // old C++ ABI
 254             useGCC32ABI = false;
 255         } else {
 256             // new C++ ABI
 257             useGCC32ABI = true;
 258         }
 259     }
 260 
 261     /** From the Debugger interface via JVMDebugger */
 262     public synchronized void attach(int processID) throws DebuggerException {
 263         checkAttached();
 264         threadList = new ArrayList();
 265         loadObjectList = new ArrayList();
 266         class AttachTask implements WorkerThreadTask {
 267            int pid;
 268            public void doit(BsdDebuggerLocal debugger) {
 269               debugger.attach0(pid);
 270               debugger.attached = true;
 271               debugger.isCore = false;
 272               findABIVersion();


 351         return null;
 352     }
 353 
 354     /* called from lookup */
 355     private long handleGCC32ABI(long addr, String symbol) throws DebuggerException {
 356         if (useGCC32ABI && symbol.startsWith("_ZTV")) {
 357             return addr + (2 * machDesc.getAddressSize());
 358         } else {
 359             return addr;
 360         }
 361     }
 362 
 363     /** From the SymbolLookup interface via Debugger and JVMDebugger */
 364     public synchronized Address lookup(String objectName, String symbol) {
 365         requireAttach();
 366         if (!attached) {
 367             return null;
 368         }
 369 
 370         if (isCore) {
 371             // MacOSX symbol with "_" as leading
 372             long addr = lookupByName0(objectName, isDarwin ? "_" + symbol : symbol);
 373             return (addr == 0)? null : new BsdAddress(this, handleGCC32ABI(addr, symbol));
 374         } else {
 375             class LookupByNameTask implements WorkerThreadTask {
 376                 String objectName, symbol;
 377                 Address result;
 378 
 379                 public void doit(BsdDebuggerLocal debugger) {
 380                     long addr = debugger.lookupByName0(objectName, symbol);
 381                     result = (addr == 0 ? null : new BsdAddress(debugger, handleGCC32ABI(addr, symbol)));
 382                 }
 383             }
 384 
 385             LookupByNameTask task = new LookupByNameTask();
 386             task.objectName = objectName;
 387             task.symbol = symbol;
 388             workerThread.execute(task);
 389             return task.result;
 390         }
 391     }
 392 


 395         Address addr = lookup(objectName, symbol);
 396         if (addr == null) {
 397             return null;
 398         }
 399         return addr.addOffsetToAsOopHandle(0);
 400     }
 401 
 402     /** From the Debugger interface */
 403     public MachineDescription getMachineDescription() {
 404         return machDesc;
 405     }
 406 
 407     //----------------------------------------------------------------------
 408     // Implementation of ThreadAccess interface
 409     //
 410 
 411     /** From the ThreadAccess interface via Debugger and JVMDebugger */
 412     public ThreadProxy getThreadForIdentifierAddress(Address threadIdAddr, Address uniqueThreadIdAddr) {
 413         return new BsdThread(this, threadIdAddr, uniqueThreadIdAddr);
 414     }
 415 
 416     @Override
 417     public ThreadProxy getThreadForIdentifierAddress(Address addr) {
 418         throw new RuntimeException("unimplemented");
 419     }
 420 

 421     /** From the ThreadAccess interface via Debugger and JVMDebugger */
 422     public ThreadProxy getThreadForThreadId(long id) {
 423         return new BsdThread(this, id);
 424     }
 425 
 426     //----------------------------------------------------------------------
 427     // Internal routines (for implementation of BsdAddress).
 428     // These must not be called until the MachineDescription has been set up.
 429     //
 430 
 431     /** From the BsdDebugger interface */
 432     public String addressValueToString(long address) {
 433         return utils.addressValueToString(address);
 434     }
 435 
 436     /** From the BsdDebugger interface */
 437     public BsdAddress readAddress(long address)
 438             throws UnmappedAddressException, UnalignedAddressException {
 439         long value = readAddressValue(address);
 440         return (value == 0 ? null : new BsdAddress(this, value));


 593                         result = new ReadResult(res);
 594                     else
 595                         result = new ReadResult(address);
 596                 }
 597             }
 598 
 599             ReadBytesFromProcessTask task = new ReadBytesFromProcessTask();
 600             task.address = address;
 601             task.numBytes = numBytes;
 602             workerThread.execute(task);
 603             return task.result;
 604         }
 605     }
 606 
 607     public void writeBytesToProcess(long address, long numBytes, byte[] data)
 608         throws UnmappedAddressException, DebuggerException {
 609         // FIXME
 610         throw new DebuggerException("Unimplemented");
 611     }
 612 
 613     /** this functions used for core file reading and called from native attach0,
 614         it returns an array of long integers as
 615         [thread_id, stack_start, stack_end, thread_id, stack_start, stack_end, ....] for
 616         all java threads recorded in Threads. Also adds the ThreadProxy to threadList */
 617     public long[] getJavaThreadsInfo() {
 618         requireAttach();
 619         Threads threads = VM.getVM().getThreads();
 620         int len = threads.getNumberOfThreads();
 621         long[] result = new long[len * 3];    // triple
 622         JavaThread t = threads.first();
 623         long beg, end;
 624         int i = 0;
 625         while (t != null) {
 626             end = t.getStackBaseValue();
 627             beg = end - t.getStackSize();
 628             BsdThread bsdt = (BsdThread)t.getThreadProxy();
 629             long uid = bsdt.getUniqueThreadId();
 630             if (threadList != null) threadList.add(bsdt);
 631             result[i] = uid;
 632             result[i + 1] = beg;
 633             result[i + 2] = end; 
 634             t = t.next();
 635             i += 3;
 636         }
 637         return result;
 638     }
 639 
 640     static {
 641         System.loadLibrary("saproc");
 642         init0();
 643     }
 644 }
agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File