sa-jdi

              case 255: 
                break;
              default: 
                System.err.println("WARNING: unexpected leaf index " + fieldIter.typeStringLeaf() + " in field list for type " + iter.getTypeIndex());
              }
              if (advance) {
                fieldIter.typeStringNext();
              }
            }
          }
          putType(type);
          break;
        case 4102: 
          BasicCompoundType type = new BasicCompoundType(iter.getUnionName(), iter.getUnionSize(), CompoundTypeKind.UNION);
          if ((iter.getClassProperty() & 0x80) == 0)
          {
            DebugVC50TypeIterator fieldIter = iter.getUnionFieldListIterator();
            if (Assert.ASSERTS_ENABLED) {
              Assert.that(fieldIter.typeStringLeaf() == 4611, "Expected field list");
            }
            boolean advance = false;
            while (!fieldIter.typeStringDone())
            {
              advance = true;
              switch (fieldIter.typeStringLeaf())
              {
              case 4611: 
                break;
              case 5120: 
                break;
              case 5121: 
                break;
              case 5122: 
                break;
              case 5124: 
                fieldIter = fieldIter.getIndexIterator();
                advance = false;
                break;
              case 5125: 
                BasicField field = new BasicField(fieldIter.getMemberName(), getTypeByIndex(fieldIter.getMemberType()), memberAttributeToAccessControl(fieldIter.getMemberAttribute()), false);
                
                field.setOffset(fieldIter.getMemberOffset());
                type.addField(field);
                break;
              case 5126: 
                System.err.println("WARNING: I didn't think unions could contain static fields...");
                BasicField field = new BasicField(fieldIter.getStaticName(), getTypeByIndex(fieldIter.getStaticType()), memberAttributeToAccessControl(fieldIter.getStaticAttribute()), true);
                
                type.addField(field);
                break;
              case 5127: 
                break;
              case 5131: 
                break;
              case 5128: 
                break;
              case 5133: 
                break;
              case 5129: 
                break;
              case 5130: 
                break;
              case 5132: 
                break;
              case 5134: 
                break;
              case 240: 
              case 241: 
              case 242: 
              case 243: 
              case 244: 
              case 245: 
              case 246: 
              case 247: 
              case 248: 
              case 249: 
              case 250: 
              case 251: 
              case 252: 
              case 253: 
              case 254: 
              case 255: 
                break;
              default: 
                System.err.println("WARNING: unexpected leaf index " + fieldIter.typeStringLeaf() + " in field list for union of type " + iter.getTypeIndex());
              }
              if (advance) {
                fieldIter.typeStringNext();
              }
            }
          }
          putType(type);
          break;
        case 4103: 
          String name = iter.getEnumName();
          BasicEnumType enumType = null;
          if ((name == null) || (name.equals("")))
          {
            if (unnamedEnum == null) {
              unnamedEnum = new BasicEnumType(null, getTypeByIndex(iter.getEnumType()));
            }
            enumType = unnamedEnum;
          }
          else
          {
            enumType = new BasicEnumType(name, getTypeByIndex(iter.getEnumType()));
          }
          DebugVC50TypeIterator fieldIter = iter.getEnumFieldListIterator();
          if (Assert.ASSERTS_ENABLED) {
            Assert.that(fieldIter.typeStringLeaf() == 4611, "Expected field list");
          }
          boolean advance = false;
          while (!fieldIter.typeStringDone())
          {
            advance = true;
            switch (fieldIter.typeStringLeaf())
            {
            case 4611: 
              break;
            case 1027: 
              String enumName = fieldIter.getEnumerateName();
              long enumVal = fieldIter.getEnumerateValue();
              enumType.addEnum(enumName, enumVal);
              break;
            case 5124: 
              fieldIter = fieldIter.getIndexIterator();
              advance = false;
              break;
            case 240: 
            case 241: 
            case 242: 
            case 243: 
            case 244: 
            case 245: 
            case 246: 
            case 247: 
            case 248: 
            case 249: 
            case 250: 
            case 251: 
            case 252: 
            case 253: 
            case 254: 
            case 255: 
              break;
            default: 
              System.err.println("WARNING: unexpected leaf index " + fieldIter.typeStringLeaf() + " in field list for enum of type " + iter.getTypeIndex());
            }
            if (advance) {
              fieldIter.typeStringNext();
            }
          }
          putType(enumType);
          break;
        case 4104: 
          Type retType = getTypeByIndex(iter.getProcedureReturnType());
          BasicFunctionType func = new BasicFunctionType(null, 4, retType);
          DebugVC50TypeIterator argIter = iter.getProcedureArgumentListIterator();
          if (Assert.ASSERTS_ENABLED) {
            Assert.that(argIter.typeStringLeaf() == 4609, "Expected argument list");
          }
          for (int i = 0; i < argIter.getArgListCount(); i++) {
            func.addArgumentType(getTypeByIndex(argIter.getArgListType(i)));
          }
          putType(func);
          break;
        case 4105: 
          Type retType = getTypeByIndex(iter.getMFunctionReturnType());
          Type container = getTypeByIndex(iter.getMFunctionContainingClass());
          Type thisType = getTypeByIndex(iter.getMFunctionThis());
          long thisAdjust = iter.getMFunctionThisAdjust();
          BasicMemberFunctionType func = new BasicMemberFunctionType(null, 4, retType, container, thisType, thisAdjust);
          
          DebugVC50TypeIterator argIter = iter.getMFunctionArgumentListIterator();
          for (int i = 0; i < argIter.getArgListCount(); i++) {
            func.addArgumentType(getTypeByIndex(argIter.getArgListType(i)));
          }
          putType(func);
          break;
        case 10: 
          break;
        case 4107: 
          System.err.println("FIXME: don't know what to do with LF_BARRAY leaves (convert to pointers?"); break;
        case 14: 
          break;
        case 15: 
          break;
        case 4108: 
          System.err.println("FIXME: don't know what to do with LF_DIMARRAY leaves yet"); break;
        case 4109: 
          break;
        case 4110: 
          break;
        case 20: 
          break;
        case 4111: 
          break;
        case 22: 
          break;
        case 4608: 
          break;
        case 4609: 
          skipTypeRecord(); break;
        case 4610: 
          System.err.println("FIXME: handle default arguments (dereference the type)"); break;
        case 4611: 
          skipTypeRecord(); break;
        case 4612: 
          break;
        case 4613: 
          Type underlyingType = getTypeByIndex(iter.getBitfieldFieldType());
          BasicBitType bit = new BasicBitType(underlyingType, iter.getBitfieldLength() & 0xFF, iter.getBitfieldPosition() & 0xFF);
          
          putType(bit);
          break;
        case 4614: 
          break;
        case 4615: 
        case 4616: 
        case 4617: 
        case 4618: 
          break;
        case 524: 
          break;
        case 240: 
        case 241: 
        case 242: 
        case 243: 
        case 244: 
        case 245: 
        case 246: 
        case 247: 
        case 248: 
        case 249: 
        case 250: 
        case 251: 
        case 252: 
        case 253: 
        case 254: 
        case 255: 
          break;
        default: 
          System.err.println("Unexpected leaf index " + iter.typeStringLeaf() + " at offset 0x" + Integer.toHexString(iter.typeStringOffset()));
        }
        if (!iter.typeStringDone()) {
          iter.typeStringNext();
        }
      }
    }
    DebugVC50SubsectionDirectory dir = vc50.getSubsectionDirectory();
    int moduleNumber = 0;
    for (int i = 0; i < dir.getNumEntries(); i++)
    {
      DebugVC50Subsection ss = dir.getSubsection(i);
      int ssType = ss.getSubsectionType();
      boolean process = false;
      if ((ssType == 297) || (ssType == 298) || (ssType == 308))
      {
        DebugVC50SSSymbolBase syms = (DebugVC50SSSymbolBase)ss;
        symIter = syms.getSymbolIterator();
        process = true;
      }
      if (ssType == 293)
      {
        DebugVC50SSAlignSym syms = (DebugVC50SSAlignSym)ss;
        symIter = syms.getSymbolIterator();
        process = true;
      }
      if (process) {
        for (; !symIter.done(); symIter.next()) {
          switch (symIter.getType())
          {
          case 1: 
            break;
          case 5: 
            break;
          case 6: 
            try
            {
              if (endsToSkip == 0) {
                blockStack.pop();
              } else {
                endsToSkip -= 1;
              }
            }
            catch (EmptyStackException e)
            {
              System.err.println("WARNING: mismatched block begins/ends in debug information");
            }
          case 7: 
            break;
          case 8: 
            break;
          case 9: 
            break;
          case 10: 
            break;
          case 11: 
            break;
          case 12: 
            break;
          case 13: 
            break;
          case 14: 
            break;
          case 4097: 
            break;
          case 4098: 
            break;
          case 4099: 
            break;
          case 4100: 
            break;
          case 4101: 
            break;
          case 4102: 
            LocalSym sym = new BasicLocalSym(symIter.getBPRelName(), getTypeByIndex(symIter.getBPRelType()), symIter.getBPRelOffset());
            
            addLocalToCurBlock(sym);
            break;
          case 4103: 
          case 4104: 
            boolean isModuleLocal = symIter.getType() == 4103;
            
            GlobalSym sym = new BasicGlobalSym(symIter.getLGDataName(), getTypeByIndex(symIter.getLGDataType()), newAddress(symIter.getLGDataOffset(), symIter.getLGDataSegment()), isModuleLocal);
            
            addGlobalSym(sym);
            break;
          case 4105: 
            break;
          case 4106: 
          case 4107: 
            BasicFunctionSym sym = new BasicFunctionSym(newLazyBlockSym(symIter.getLGProcParentOffset()), symIter.getLGProcLength(), newAddress(symIter.getLGProcOffset(), symIter.getLGProcSegment()), symIter.getLGProcName(), getTypeByIndex(symIter.getLGProcType()), symIter.getType() == 4106);
            
            addBlock(sym);
            break;
          case 518: 
            skipEnd();
            break;
          case 519: 
            BasicBlockSym sym = new BasicBlockSym(newLazyBlockSym(symIter.getBlockParentOffset()), symIter.getBlockLength(), newAddress(symIter.getBlockOffset(), symIter.getBlockSegment()), symIter.getBlockName());
            
            addBlock(sym);
            break;
          case 520: 
            break;
          case 521: 
            break;
          case 522: 
            break;
          case 4108: 
            break;
          case 4109: 
            break;
          case 4110: 
            break;
          case 4111: 
            break;
          case 1024: 
            break;
          case 1025: 
            break;
          case 1026: 
            break;
          default: 
            if ((symIter.getType() != 0) && (symIter.getType() != 4115)) {
              System.err.println("  NOTE: Unexpected symbol of type " + symIter.getType() + " at offset 0x" + Integer.toHexString(symIter.getOffset()));
            }
            break;
          }
        }
      }
    }
    for (int i = 0; i < dir.getNumEntries(); i++)
    {
      DebugVC50Subsection ss = dir.getSubsection(i);
      if (ss.getSubsectionType() == 295)
      {
        DebugVC50SSSrcModule srcMod = (DebugVC50SSSrcModule)ss;
        for (int sf = 0; sf < srcMod.getNumSourceFiles(); sf++)
        {
          DebugVC50SrcModFileDesc desc = srcMod.getSourceFileDesc(sf);
          
          String name = desc.getSourceFileName().intern();
          for (int cs = 0; cs < desc.getNumCodeSegments(); cs++)
          {
            DebugVC50SrcModLineNumberMap map = desc.getLineNumberMap(cs);
            SectionHeader seg = file.getHeader().getSectionHeader(map.getSegment());
            for (int lp = 0; lp < map.getNumSourceLinePairs(); lp++)
            {
              Address startPC = base.addOffsetTo(seg.getVirtualAddress() + map.getCodeOffset(lp));
              
              Address endPC = base.addOffsetTo(seg.getSize());
              db.addLineNumberInfo(new BasicLineNumberInfo(name, map.getLineNumber(lp), startPC, endPC));
            }
          }
        }
      }
    }
    db.resolve(new ResolveListener()
    {
      public void resolveFailed(Type containingType, LazyType failedResolve, String detail)
      {
        System.err.println("WARNING: failed to resolve type of index " + ((Integer)failedResolve.getKey()).intValue() + " in type " + containingType.getName() + " (class " + containingType.getClass().getName() + ") while " + detail);
      }
      
      public void resolveFailed(Type containingType, String staticFieldName)
      {
        System.err.println("WARNING: failed to resolve address of static field \"" + staticFieldName + "\" in type " + containingType.getName());
      }
      
      public void resolveFailed(Sym containingSymbol, LazyType failedResolve, String detail)
      {
        System.err.println("WARNING: failed to resolve type of index " + ((Integer)failedResolve.getKey()).intValue() + " in symbol of type " + containingSymbol.getClass().getName() + " while " + detail);
      }
      
      public void resolveFailed(Sym containingSymbol, LazyBlockSym failedResolve, String detail)
      {
        System.err.println("WARNING: failed to resolve block at offset 0x" + Integer.toHexString(((Integer)failedResolve.getKey()).intValue()) + " in symbol of type " + containingSymbol.getClass().getName() + " while " + detail);
      }
    });
    db.endConstruction();
    
    return db;
  }
  
  private static DebugVC50 getDebugVC50(COFFFile file)
  {
    COFFHeader header = file.getHeader();
    OptionalHeader opt = header.getOptionalHeader();
    if (opt == null) {
      return null;
    }
    OptionalHeaderDataDirectories dd = opt.getDataDirectories();
    if (dd == null) {
      return null;
    }
    DebugDirectory debug = dd.getDebugDirectory();
    if (debug == null) {
      return null;
    }
    for (int i = 0; i < debug.getNumEntries(); i++)
    {
      DebugDirectoryEntry entry = debug.getEntry(i);
      if (entry.getType() == 2) {
        return entry.getDebugVC50();
      }
    }
    return null;
  }
  
  private DebugVC50SSSegMap getSegMap()
  {
    return (DebugVC50SSSegMap)findSubsection((short)301);
  }
  
  private DebugVC50SSGlobalTypes getGlobalTypes()
  {
    return (DebugVC50SSGlobalTypes)findSubsection((short)299);
  }
  
  private DebugVC50SSGlobalSym getGlobalSymbols()
  {
    return (DebugVC50SSGlobalSym)findSubsection((short)297);
  }
  
  private DebugVC50Subsection findSubsection(short ssType)
  {
    DebugVC50SubsectionDirectory dir = vc50.getSubsectionDirectory();
    for (int i = 0; i < dir.getNumEntries(); i++)
    {
      DebugVC50Subsection ss = dir.getSubsection(i);
      if (ss.getSubsectionType() == ssType) {
        return ss;
      }
    }
    throw new DebuggerException("Unable to find subsection of type " + ssType);
  }
  
  private void putType(Type t)
  {
    db.addType(new Integer(iter.getTypeIndex()), t);
  }
  
  private Address newAddress(int offset, short segment)
  {
    int seg = segment & 0xFFFF;
    
    SectionHeader section = file.getHeader().getSectionHeader(seg);
    
    return base.addOffsetTo(section.getVirtualAddress() + offset);
  }
  
  private BasicType getTypeByIndex(int intIndex)
  {
    Integer index = new Integer(intIndex);
    if (intIndex <= 4095)
    {
      BasicType type = (BasicType)primIndexToTypeMap.get(index);
      if (type != null) {
        return type;
      }
      int primMode = intIndex & 0x700;
      if (primMode == 0)
      {
        int primType = intIndex & 0x70;
        switch (primType)
        {
        case 16: 
        case 32: 
          boolean unsigned = primType == 32;
          int size = 0;
          String name = null;
          switch (intIndex & 0x7)
          {
          case 0: 
            size = 1;name = "char"; break;
          case 1: 
            size = 2;name = "short"; break;
          case 2: 
            size = 4;name = "int"; break;
          case 3: 
            size = 8;name = "__int64"; break;
          default: 
            throw new DebuggerException("Illegal size of integer type " + intIndex);
          }
          type = new BasicIntType(name, size, unsigned);
          break;
        case 48: 
          int size = 0;
          switch (intIndex & 0x7)
          {
          case 0: 
            size = 1; break;
          case 1: 
            size = 2; break;
          case 2: 
            size = 4; break;
          case 3: 
            size = 8; break;
          default: 
            throw new DebuggerException("Illegal size of boolean type " + intIndex);
          }
          type = new BasicIntType("bool", size, false);
          break;
        case 64: 
          switch (intIndex & 0x7)
          {
          case 0: 
            type = new BasicFloatType("float", 4);
            break;
          case 1: 
            type = new BasicDoubleType("double", 8);
            break;
          default: 
            throw new DebuggerException("Unsupported floating-point size in type " + intIndex);
          }
          break;
        case 112: 
          switch (intIndex & 0x7)
          {
          case 0: 
            type = new BasicIntType("char", 1, false); break;
          case 1: 
            type = new BasicIntType("wchar", 2, false); break;
          case 2: 
            type = new BasicIntType("short", 2, false); break;
          case 3: 
            type = new BasicIntType("short", 2, true); break;
          case 4: 
            type = new BasicIntType("int", 4, false); break;
          case 5: 
            type = new BasicIntType("int", 4, true); break;
          case 6: 
            type = new BasicIntType("__int64", 8, false); break;
          case 7: 
            type = new BasicIntType("__int64", 8, true); break;
          default: 
            throw new DebuggerException("Illegal REALLY_INT size in type " + intIndex);
          }
          break;
        case 0: 
          switch (intIndex & 0x7)
          {
          case 0: 
          case 3: 
            type = new BasicVoidType(); break;
          default: 
            throw new DebuggerException("Don't know how to handle reserved special type " + intIndex);
          }
          break;
        default: 
          throw new DebuggerException("Don't know how to handle reserved type " + intIndex);
        }
      }
      else
      {
        Type targetType = getTypeByIndex(intIndex & 0xF8FF);
        
        type = new BasicPointerType(4, targetType);
      }
      if (Assert.ASSERTS_ENABLED) {
        Assert.that(type != null, "Got null Type for primitive type " + intIndex);
      }
      primIndexToTypeMap.put(index, type);
      return type;
    }
    return new LazyType(index);
  }
  
  private void addBlock(BlockSym block)
  {
    db.addBlock(new Integer(symIter.getOffset()), block);
    blockStack.push(block);
  }
  
  private void skipEnd()
  {
    endsToSkip += 1;
  }
  
  private BlockSym newLazyBlockSym(int offset)
  {
    if (offset == 0) {
      return null;
    }
    return new LazyBlockSym(new Integer(offset));
  }
  
  private int memberAttributeToAccessControl(short memberAttribute)
  {
    int acc = memberAttribute & 0x3;
    switch (acc)
    {
    case 0: 
      return 0;
    case 1: 
      return 1;
    case 2: 
      return 2;
    case 3: 
      return 3;
    }
    throw new RuntimeException("Should not reach here");
  }
  
  private void addLocalToCurBlock(LocalSym local)
  {
    ((BasicBlockSym)blockStack.peek()).addLocal(local);
  }
  
  private void addGlobalSym(GlobalSym sym)
  {
    db.addGlobalSym(sym);
  }
  
  private void skipTypeRecord()
  {
    while (!iter.typeStringDone()) {
      iter.typeStringNext();
    }
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.debugger.windbg.WindbgCDebugInfoBuilder
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.debugger.windbg;

import java.util.List;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.debugger.DebuggerException;
import sun.jvm.hotspot.debugger.JVMDebugger;

public abstract interface WindbgDebugger
  extends JVMDebugger
{
  public abstract String addressValueToString(long paramLong)
    throws DebuggerException;
  
  public abstract boolean readJBoolean(long paramLong)
    throws DebuggerException;
  
  public abstract byte readJByte(long paramLong)
    throws DebuggerException;
  
  public abstract char readJChar(long paramLong)
    throws DebuggerException;
  
  public abstract double readJDouble(long paramLong)
    throws DebuggerException;
  
  public abstract float readJFloat(long paramLong)
    throws DebuggerException;
  
  public abstract int readJInt(long paramLong)
    throws DebuggerException;
  
  public abstract long readJLong(long paramLong)
    throws DebuggerException;
  
  public abstract short readJShort(long paramLong)
    throws DebuggerException;
  
  public abstract long readCInteger(long paramLong1, long paramLong2, boolean paramBoolean)
    throws DebuggerException;
  
  public abstract WindbgAddress readAddress(long paramLong)
    throws DebuggerException;
  
  public abstract WindbgAddress readCompOopAddress(long paramLong)
    throws DebuggerException;
  
  public abstract WindbgOopHandle readOopHandle(long paramLong)
    throws DebuggerException;
  
  public abstract WindbgOopHandle readCompOopHandle(long paramLong)
    throws DebuggerException;
  
  public abstract long[] getThreadIntegerRegisterSet(long paramLong)
    throws DebuggerException;
  
  public abstract Address newAddress(long paramLong)
    throws DebuggerException;
  
  public abstract long getThreadIdFromSysId(long paramLong)
    throws DebuggerException;
  
  public abstract List getThreadList()
    throws DebuggerException;
  
  public abstract List getLoadObjectList()
    throws DebuggerException;
  
  public abstract int getAddressSize();
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.debugger.windbg.WindbgDebugger
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.debugger.windbg;

import sun.jvm.hotspot.debugger.DebuggerUtilities;
import sun.jvm.hotspot.debugger.UnalignedAddressException;

final class WindbgDebuggerLocal$1
  extends DebuggerUtilities
{
  private final WindbgDebuggerLocal this$0;
  
  WindbgDebuggerLocal$1(WindbgDebuggerLocal paramWindbgDebuggerLocal, long x0, boolean x1)
  {
    super(x0, x1);
  }
  
  public void checkAlignment(long address, long alignment)
  {
    if ((address % alignment != 0L) && ((alignment != 8L) || (address % 4L != 0L))) {
      throw new UnalignedAddressException("Trying to read at address: " + addressValueToString(address) + " with alignment: " + alignment, address);
    }
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.1
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.debugger.windbg;

import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.debugger.cdbg.ClosestSymbol;

final class WindbgDebuggerLocal$2
  extends DLL
{
  private final WindbgDebuggerLocal this$0;
  
  WindbgDebuggerLocal$2(WindbgDebuggerLocal paramWindbgDebuggerLocal, WindbgDebugger x0, String x1, long x2, Address x3)
  {
    super(x0, x1, x2, x3);
  }
  
  public ClosestSymbol closestSymbolToPC(Address pcAsAddr)
  {
    long pc = this$0.getAddressValue(pcAsAddr);
    ClosestSymbol sym = WindbgDebuggerLocal.access$000(this$0, pc);
    if (sym == null) {
      return super.closestSymbolToPC(pcAsAddr);
    }
    return sym;
  }
}

/* Location:
 * Qualified Name:     sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.2
 * Java Class Version: 1.4 (48.0)
 * JD-Core Version:    0.7.1
 */
package sun.jvm.hotspot.debugger.windbg;

import java.io.File;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.debugger.DebuggerBase;
import sun.jvm.hotspot.debugger.DebuggerException;
import sun.jvm.hotspot.debugger.DebuggerUtilities;
import sun.jvm.hotspot.debugger.MachineDescription;
import sun.jvm.hotspot.debugger.NotInHeapException;
import sun.jvm.hotspot.debugger.OopHandle;
import sun.jvm.hotspot.debugger.PageCache;
import sun.jvm.hotspot.debugger.ReadResult;
import sun.jvm.hotspot.debugger.ThreadProxy;
import sun.jvm.hotspot.debugger.UnalignedAddressException;
import sun.jvm.hotspot.debugger.UnmappedAddressException;
import sun.jvm.hotspot.debugger.cdbg.CDebugger;
import sun.jvm.hotspot.debugger.cdbg.ClosestSymbol;
import sun.jvm.hotspot.debugger.windbg.amd64.WindbgAMD64ThreadFactory;
import sun.jvm.hotspot.debugger.windbg.ia64.WindbgIA64ThreadFactory;
import sun.jvm.hotspot.debugger.windbg.x86.WindbgX86ThreadFactory;
import sun.jvm.hotspot.utilities.PlatformInfo;

public class WindbgDebuggerLocal
  extends DebuggerBase
  implements WindbgDebugger
{
  private PageCache cache;
  private boolean attached;
  private boolean isCore;
  private Map nameToDllMap;
  private List loadObjects;
  private CDebugger cdbg;
  private Map threadIntegerRegisterSet;
  private List threadList;
  private long ptrIDebugClient;
  private long ptrIDebugControl;
  private long ptrIDebugDataSpaces;
  private long ptrIDebugOutputCallbacks;
  private long ptrIDebugAdvanced;
  private long ptrIDebugSymbols;
  private long ptrIDebugSystemObjects;
  private WindbgThreadFactory threadFactory;
  private static String imagePath;
  private static String symbolPath;
  private static boolean useNativeLookup;
  
  public WindbgDebuggerLocal(MachineDescription machDesc, boolean useCache)
    throws DebuggerException
  {
    this.machDesc = machDesc;
    utils = new DebuggerUtilities(machDesc.getAddressSize(), machDesc.isBigEndian())
    {
      public void checkAlignment(long address, long alignment)
      {
        if ((address % alignment != 0L) && ((alignment != 8L) || (address % 4L != 0L))) {
          throw new UnalignedAddressException("Trying to read at address: " + addressValueToString(address) + " with alignment: " + alignment, address);
        }
      }
    };
    String cpu = PlatformInfo.getCPU();
    if (cpu.equals("x86")) {
      threadFactory = new WindbgX86ThreadFactory(this);
    } else if (cpu.equals("amd64")) {
      threadFactory = new WindbgAMD64ThreadFactory(this);
    } else if (cpu.equals("ia64")) {
      threadFactory = new WindbgIA64ThreadFactory(this);
    }
    if (useCache) {
      initCache(4096L, 4096L);
    }
  }
  
  public boolean hasProcessList()
    throws DebuggerException
  {
    return false;
  }
  
  public List getProcessList()
    throws DebuggerException
  {
    return null;
  }
  
  public synchronized void attach(int processID)
    throws DebuggerException
  {
    attachInit();
    attach0(processID);
    attached = true;
    isCore = false;
  }
  
  public synchronized void attach(String executableName, String coreFileName)
    throws DebuggerException
  {
    attachInit();
    attach0(executableName, coreFileName);
    attached = true;
    isCore = true;
  }
  
  public List getLoadObjectList()
  {
    requireAttach();
    return loadObjects;
  }
  
  public synchronized boolean detach()
  {
    if (!attached) {
      return false;
    }
    if (nameToDllMap != null)
    {
      for (Iterator iter = nameToDllMap.values().iterator(); iter.hasNext();)
      {
        DLL dll = (DLL)iter.next();
        dll.close();
      }
      nameToDllMap = null;
      loadObjects = null;
    }
    cdbg = null;
    clearCache();
    
    threadIntegerRegisterSet = null;
    threadList = null;
    try
    {
      detach0();
    }
    finally
    {
      attached = false;
      resetNativePointers();
    }
    return true;
  }
  
  public Address parseAddress(String addressString)
    throws NumberFormatException
  {
    return newAddress(utils.scanAddress(addressString));
  }
  
  public String getOS()
  {
    return PlatformInfo.getOS();
  }
  
  public String getCPU()
  {
    return PlatformInfo.getCPU();
  }
  
  public boolean hasConsole()
    throws DebuggerException
  {
    return true;
  }
  
  public synchronized String consoleExecuteCommand(String cmd)
    throws DebuggerException
  {
    requireAttach();
    if (!attached) {
      throw new DebuggerException("debugger not yet attached to a Dr. Watson dump!");
    }
    return consoleExecuteCommand0(cmd);
  }
  
  public String getConsolePrompt()
    throws DebuggerException
  {
    return "(windbg)";
  }
  
  public CDebugger getCDebugger()
    throws DebuggerException
  {
    if (cdbg == null) {
      if (!getCPU().equals("ia64")) {
        cdbg = new WindbgCDebugger(this);
      }
    }
    return cdbg;
  }
  
  public synchronized Address lookup(String objectName, String symbol)
  {
    requireAttach();
    return newAddress(lookupByName(objectName, symbol));
  }
  
  public synchronized OopHandle lookupOop(String objectName, String symbol)
  {
    Address addr = lookup(objectName, symbol);
    if (addr == null) {
      return null;
    }
    return addr.addOffsetToAsOopHandle(0L);
  }
  
  public synchronized ClosestSymbol lookup(long address)
  {
    return lookupByAddress0(address);
  }
  
  public MachineDescription getMachineDescription()
  {
    return machDesc;
  }
  
  public ThreadProxy getThreadForIdentifierAddress(Address addr)
  {
    return threadFactory.createThreadWrapper(addr);
  }
  
  public ThreadProxy getThreadForThreadId(long handle)
  {
    throw new DebuggerException("Unimplemented!");
  }
  
  public long getThreadIdFromSysId(long sysId)
    throws DebuggerException
  {
    requireAttach();
    return getThreadIdFromSysId0(sysId);
  }
  
  public long readJLong(long address)
    throws UnmappedAddressException, UnalignedAddressException
  {
    checkJavaConfigured();
    
    utils.checkAlignment(address, jintSize);
    byte[] data = readBytes(address, jlongSize);
    return utils.dataToJLong(data, jlongSize);
  }
  
  public String addressValueToString(long address)
  {
    return utils.addressValueToString(address);
  }
  
  public WindbgAddress readAddress(long address)
    throws UnmappedAddressException, UnalignedAddressException
  {
    return (WindbgAddress)newAddress(readAddressValue(address));
  }
  
  public WindbgAddress readCompOopAddress(long address)
    throws UnmappedAddressException, UnalignedAddressException
  {
    return (WindbgAddress)newAddress(readCompOopAddressValue(address));
  }
  
  public WindbgOopHandle readOopHandle(long address)
    throws UnmappedAddressException, UnalignedAddressException, NotInHeapException
  {
    long value = readAddressValue(address);
    return value == 0L ? null : new WindbgOopHandle(this, value);
  }
  
  public WindbgOopHandle readCompOopHandle(long address)
    throws UnmappedAddressException, UnalignedAddressException, NotInHeapException
  {
    long value = readCompOopAddressValue(address);
    return value == 0L ? null : new WindbgOopHandle(this, value);
  }
  
  public int getAddressSize()
  {
    return (int)machDesc.getAddressSize();
  }
  
  private synchronized void setThreadIntegerRegisterSet(long threadId, long[] regs)
  {
    threadIntegerRegisterSet.put(new Long(threadId), regs);
  }
  
  private synchronized void addThread(long sysId)
  {
    threadList.add(threadFactory.createThreadWrapper(sysId));
  }
  
  public synchronized long[] getThreadIntegerRegisterSet(long threadId)
    throws DebuggerException
  {
    requireAttach();
    return (long[])threadIntegerRegisterSet.get(new Long(threadId));
  }
  
  public synchronized List getThreadList()
    throws DebuggerException
  {
    requireAttach();
    return threadList;
  }
  
  private String findFullPath(String file)
  {
    File f = new File(file);
    if (f.exists()) {
      return file;
    }
    file = f.getName();
    StringTokenizer st = new StringTokenizer(imagePath, File.pathSeparator);
    while (st.hasMoreTokens())
    {
      f = new File(st.nextToken(), file);
      if (f.exists()) {
        return f.getPath();
      }
    }
    return null;
  }
  
  private synchronized void addLoadObject(String file, long size, long base)
  {
    String path = findFullPath(file);
    if (path != null)
    {
      DLL dll = null;
      if (useNativeLookup) {
        dll = new DLL(this, path, size, newAddress(base))
        {
          public ClosestSymbol closestSymbolToPC(Address pcAsAddr)
          {
            long pc = getAddressValue(pcAsAddr);
            ClosestSymbol sym = WindbgDebuggerLocal.this.lookupByAddress0(pc);
            if (sym == null) {
              return super.closestSymbolToPC(pcAsAddr);
            }
            return sym;
          }
        };
      } else {
        dll = new DLL(this, path, size, newAddress(base));
      }
      loadObjects.add(dll);
      nameToDllMap.put(new File(file).getName(), dll);
    }
  }
  
  public long getAddressValue(Address addr)
  {
    if (addr == null) {
      return 0L;
    }
    return ((WindbgAddress)addr).getValue();
  }
  
  public Address newAddress(long value)
  {
    if (value == 0L) {
      return null;
    }
    return new WindbgAddress(this, value);
  }
  
  private void checkAttached()
  {
    if (attached)
    {
      String msg = isCore ? "already attached to a Dr. Watson dump!" : "already attached to a process!";
      
      throw new DebuggerException(msg);
    }
  }
  
  private void requireAttach()
  {
    if (!attached) {
      throw new RuntimeException("not attached to a process or Dr Watson dump");
    }
  }
  
  private void attachInit()
  {
    checkAttached();
    loadObjects = new ArrayList();
    nameToDllMap = new HashMap();
    threadIntegerRegisterSet = new HashMap();
    threadList = new ArrayList();
  }
  
  private void resetNativePointers()
  {
    ptrIDebugClient = 0L;
    ptrIDebugControl = 0L;
    ptrIDebugDataSpaces = 0L;
    ptrIDebugOutputCallbacks = 0L;
    ptrIDebugAdvanced = 0L;
    ptrIDebugSymbols = 0L;
    ptrIDebugSystemObjects = 0L;
  }
  
  synchronized long lookupByName(String objectName, String symbol)
  {
    long res = 0L;
    if (useNativeLookup)
    {
      res = lookupByName0(objectName, symbol);
      if (res != 0L) {
        return res;
      }
    }
    DLL dll = (DLL)nameToDllMap.get(objectName);
    if (dll != null)
    {
      WindbgAddress addr = (WindbgAddress)dll.lookupSymbol(symbol);
      if (addr != null) {
        return addr.getValue();
      }
    }
    return 0L;
  }
  
  public synchronized ReadResult readBytesFromProcess(long address, long numBytes)
    throws UnmappedAddressException, DebuggerException
  {
    requireAttach();
    byte[] res = readBytesFromProcess0(address, numBytes);
    if (res != null) {
      return new ReadResult(res);
    }
    return new ReadResult(address);
  }
  
  private DLL findDLLByName(String fullPathName)
  {
    for (Iterator iter = loadObjects.iterator(); iter.hasNext();)
    {
      DLL dll = (DLL)iter.next();
      if (dll.getName().equals(fullPathName)) {
        return dll;
      }
    }
    return null;
  }
  
  public void writeBytesToProcess(long address, long numBytes, byte[] data)
    throws UnmappedAddressException, DebuggerException
  {
    throw new DebuggerException("Unimplemented");
  }
  
  static
  {
    String dbgengPath = null;
    String dbghelpPath = null;
    String sawindbgPath = null;
    List searchList = new ArrayList();
    
    boolean loadLibraryDEBUG = System.getProperty("sun.jvm.hotspot.loadLibrary.DEBUG") != null;
    
    searchList.add(System.getProperty("java.home") + File.separator + "bin");
    sawindbgPath = (String)searchList.get(0) + File.separator + "sawindbg.dll";
    
    String DTFWHome = System.getenv("DEBUGGINGTOOLSFORWINDOWS");
    if (DTFWHome != null) {
      searchList.add(DTFWHome);
    }
    String sysRoot = System.getenv("SYSTEMROOT");
    DTFWHome = sysRoot + File.separator + ".." + File.separator + "Program Files" + File.separator + "Debugging Tools For Windows";
    
    searchList.add(DTFWHome);
    searchList.add(DTFWHome + " (x86)");
    searchList.add(DTFWHome + " (x64)");
    
    searchList.add(sysRoot + File.separator + "system32");
    for (int i = 0; i < searchList.size(); i++)
    {
      File dir = new File((String)searchList.get(i));
      if (!dir.exists())
      {
        if (loadLibraryDEBUG) {
          System.err.println("DEBUG: '" + searchList.get(i) + "': directory does not exist.");
        }
      }
      else
      {
        dbgengPath = (String)searchList.get(i) + File.separator + "dbgeng.dll";
        dbghelpPath = (String)searchList.get(i) + File.separator + "dbghelp.dll";
        
        File feng = new File(dbgengPath);
        File fhelp = new File(dbghelpPath);
        if ((feng.exists()) && (fhelp.exists())) {
          break;
        }
        if (feng.exists()) {
          System.err.println("WARNING: found '" + dbgengPath + "' but did not find '" + dbghelpPath + "'; ignoring '" + dbgengPath + "'.");
        } else if (fhelp.exists()) {
          System.err.println("WARNING: found '" + dbghelpPath + "' but did not find '" + dbgengPath + "'; ignoring '" + dbghelpPath + "'.");
        } else if (loadLibraryDEBUG) {
          System.err.println("DEBUG: searched '" + searchList.get(i) + "': dbgeng.dll and dbghelp.dll were not found.");
        }
        dbgengPath = null;
        dbghelpPath = null;
      }
    }
    if ((dbgengPath == null) || (dbghelpPath == null))
    {
      String mesg = null;
      if ((dbgengPath == null) && (dbghelpPath == null)) {
        mesg = "dbgeng.dll and dbghelp.dll cannot be found. ";
      } else if (dbgengPath == null) {
        mesg = "dbgeng.dll cannot be found (dbghelp.dll was found). ";
      } else {
        mesg = "dbghelp.dll cannot be found (dbgeng.dll was found). ";
      }
      throw new UnsatisfiedLinkError(mesg + "Please search microsoft.com for 'Debugging Tools For Windows', " + "and either download it to the default location, or download it " + "to a custom location and set environment variable " + "'DEBUGGINGTOOLSFORWINDOWS' to the pathname of that location.");
    }
    if (loadLibraryDEBUG) {
      System.err.println("DEBUG: loading '" + dbghelpPath + "'.");
    }
    System.load(dbghelpPath);
    if (loadLibraryDEBUG) {
      System.err.println("DEBUG: loading '" + dbgengPath + "'.");
    }
    System.load(dbgengPath);
    if (loadLibraryDEBUG) {
      System.err.println("DEBUG: loading '" + sawindbgPath + "'.");
    }
    System.load(sawindbgPath);
    
    imagePath = System.getProperty("sun.jvm.hotspot.debugger.windbg.imagePath
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd