home *** CD-ROM | disk | FTP | other *** search
/ Enter 1999 November / ENTER11_1.bin / WARSZTAT / SDKJava32.exe / data1.cab / fg_Samples / Samples / Debugger / java_debugger / JavaDebugger.java < prev    next >
Encoding:
Java Source  |  1999-03-17  |  12.3 KB  |  466 lines

  1. //
  2. // JavaDebugger.java
  3. //
  4. // (C) Copyright 1995 - 1999 Microsoft Corporation.  All rights reserved.
  5. //
  6.  
  7.  
  8. import com.ms.com.*;
  9. import com.ms.debug.*;
  10. import com.ms.lang.*;
  11. import java.io.IOException;
  12.  
  13.  
  14. public class JavaDebugger implements IRemoteDebugManagerCallback,
  15.                                      IRemoteProcessCallback
  16. {
  17.     /* Constants
  18.      ************/
  19.  
  20.     // Set a breakpoint at PC 0 in Hello.main().
  21.  
  22.     protected final String sDebugClass      = "Hello";
  23.     protected final String sDebugMethod     = "main";
  24.     protected final int cnBreakpointPC      = 0;
  25.  
  26.     // Debug registry key
  27.  
  28.     protected final String sJavaVMKey       = "Software\\Microsoft\\Java VM";
  29.     protected final String sDebug           = "Debug";
  30.  
  31.  
  32.     /* Fields
  33.     *********/
  34.  
  35.     protected IRemoteDebugManager m_irdm;
  36.     protected IRemoteProcess m_irp;
  37.     protected RegKey m_rkJavaVM;
  38.  
  39.  
  40.     /* Methods
  41.     **********/
  42.  
  43.     public static void main(String asCmdLine[])
  44.     {
  45.         JavaDebugger jd;
  46.  
  47.         jd = new JavaDebugger();
  48.  
  49.         jd.RunDebugger(asCmdLine);
  50.     }
  51.  
  52.     public synchronized void RunDebugger(String asCmdLine[])
  53.     {
  54.         // Exit on notify() or interrupt().
  55.  
  56.         try
  57.         {
  58.             RemoteJavaDebugManager rdm = new RemoteJavaDebugManager();
  59.  
  60.             System.out.println("Created RemoteDebugManager.");
  61.  
  62.             Initialize(rdm);
  63.  
  64.             System.out.println("Initialized debugger.");
  65.  
  66.             Run(asCmdLine);
  67.  
  68.             System.out.println("Running debuggee...");
  69.  
  70.             wait();
  71.         }
  72.         catch (InterruptedException ex)
  73.         {
  74.             ;
  75.         }
  76.         catch (IOException ioex)
  77.         {
  78.             System.err.println("Failed to start debuggee.");
  79.         }
  80.         finally
  81.         {
  82.             Terminate();
  83.  
  84.             System.out.println("Terminated debugger.");
  85.         }
  86.     }
  87.  
  88.     public void Initialize(IRemoteDebugManager irdm)
  89.     {
  90.         m_irdm = irdm;
  91.  
  92.         m_irdm.RegisterCallback(this);
  93.  
  94.         System.out.println("Registered IRemoteDebugManagerCallback.");
  95.  
  96.         CreateDebugKey();
  97.     }
  98.  
  99.     public void Terminate()
  100.     {
  101.         DeleteDebugKey();
  102.  
  103.         if (m_irp != null)
  104.         {
  105.             m_irp.Detach();
  106.             m_irp = null;
  107.  
  108.             System.out.println("Detached IRemoteProcessCallback from IRemoteProcess.");
  109.         }
  110.  
  111.         if (m_irdm != null)
  112.         {
  113.             m_irdm.Detach();
  114.             m_irdm = null;
  115.  
  116.             System.out.println("Detached IRemoteDebugManagerCallback from IRemoteDebugManager.");
  117.         }
  118.     }
  119.  
  120.     public void CreateDebugKey()
  121.     {
  122.         try
  123.         {
  124.             RegKey rkDebug;
  125.  
  126.             m_rkJavaVM = new RegKey(RegKey.getRootKey(RegKey.LOCALMACHINE_ROOT), sJavaVMKey, RegKey.KEYOPEN_CREATE);
  127.             rkDebug = new RegKey(m_rkJavaVM, sDebug, RegKey.KEYOPEN_CREATE);
  128.         }
  129.         catch (RegKeyException rkex)
  130.         {
  131.             ;
  132.         }
  133.     }
  134.  
  135.     public void DeleteDebugKey()
  136.     {
  137.         try
  138.         {
  139.             m_rkJavaVM.deleteSubKey(sDebug);
  140.         }
  141.         catch (Exception ex)
  142.         {
  143.             ;
  144.         }
  145.     }
  146.  
  147.     public void Run(String asCmdLine[]) throws IOException
  148.     {
  149.         String sCmdLine;
  150.         int i;
  151.         DebuggeeProcess dp;
  152.         int nProcessID;
  153.  
  154.         sCmdLine = new String();
  155.  
  156.         for (i = 0; i < asCmdLine.length; i++)
  157.             sCmdLine += asCmdLine[i] + " ";
  158.  
  159.         System.out.println("Debuggee command line is \"" + sCmdLine + "\".");
  160.  
  161.         dp = new DebuggeeProcess();
  162.  
  163.         dp.CreateSuspendedProcess(sCmdLine);
  164.  
  165.         System.out.println("Created suspended debuggee process.");
  166.  
  167.         nProcessID = dp.GetProcessID();
  168.  
  169.         System.out.println("Debuggee process ID is " + nProcessID + ".");
  170.  
  171.         m_irdm.RequestCreateEvent(sDebugClass, nProcessID);
  172.  
  173.         System.out.println("Requested creation event on debuggee class " + sDebugClass + " in process " + nProcessID + ".");
  174.  
  175.         dp.ResumeProcess();
  176.  
  177.         System.out.println("Resumed debuggee process.");
  178.     }
  179.  
  180.     //
  181.     // Dumps the method bytecodes for the given method.
  182.     //
  183.     static void DumpMethodBytes(IRemoteMethodField irmf)
  184.     {
  185.         com.ms.debug.ILockBytes ilb;
  186.         byte[] abyteCode;
  187.         int i;
  188.         STATSTG stat = new STATSTG();
  189.         int[] retread = new int[1];
  190.  
  191.         ilb = irmf.GetBytes();
  192.  
  193.         ilb.Stat(stat, IStream.STATFLAG_NONAME);
  194.         abyteCode = new byte[(int)stat.cbSize];
  195.         ilb.ReadAt(0, abyteCode, abyteCode.length, retread);
  196.  
  197.         System.out.println(abyteCode.length + " method bytecodes:");
  198.  
  199.         for (i = 0; i < abyteCode.length; i++)
  200.             System.out.println("\tPC[" + i + "] = " + abyteCode[i]);
  201.     }
  202.  
  203.     //
  204.     // Dumps the line number information for the given method.
  205.     //
  206.     static void DumpMethodLineInfo(IRemoteMethodField irmf)
  207.     {
  208.         try
  209.         {
  210.             IJavaEnumLINEINFO ijeli;
  211.             LINEINFO li = new LINEINFO();
  212.  
  213.             ijeli = irmf.GetLineInfo();
  214.  
  215.             System.out.println("Method line number information:");
  216.  
  217.             while (true)
  218.             {
  219.                 try
  220.                 {
  221.                     ijeli.GetNext(li);
  222.  
  223.                     System.out.println("\tPC = " + li.offPC + ", line = " + li.iLine);
  224.                 }
  225.                 catch (ComSuccessException cse)
  226.                 {
  227.                     break;
  228.                 }
  229.             }
  230.         }
  231.         catch (ComFailException cfe)
  232.         {
  233.             System.out.println("No line information for " + irmf.GetName() + "().");
  234.         }
  235.     }
  236.  
  237.     //
  238.     // Dumps the bytes for the given constant pool item.
  239.     //
  240.     static void DumpConstantPoolItem(IRemoteClassField ircf, int niItem)
  241.     {
  242.         byte[] abyteItem;
  243.         int i;
  244.         int[] retlength = new int[1];
  245.         byte[][] retabyteItem = new byte[1][];
  246.  
  247.         ircf.GetConstantPoolItem(niItem, retabyteItem, retlength);
  248.         abyteItem = retabyteItem[0];
  249.  
  250.         System.out.println(abyteItem.length + " bytes for constant pool item " + niItem + ":");
  251.  
  252.         for (i = 0; i < abyteItem.length; i++)
  253.             System.out.println("\titem[" + i + "] = " + abyteItem[i]);
  254.     }
  255.  
  256.     //
  257.     // Debugger event notification methods return an HRESULT as an int as
  258.     // follows:
  259.     //
  260.     //      S_FALSE     Continue execution.
  261.     //
  262.     //      S_OK        Suspend execution of all threads in this namespace until
  263.     //                  an IRemoteThread method is called on this thread to
  264.     //                  resume execution.
  265.     //
  266.     //      E_...       Error.
  267.     //
  268.  
  269.     // IRemoteDebugManagerCallback methods
  270.  
  271.     public void ProcessCreateEvent(IRemoteProcess irpNew, IRemoteProcess irpParent)
  272.     {
  273.         // Register process callback.
  274.  
  275.         System.out.println("Received IRemoteProcessCallback::ProcessCreateEvent().");
  276.  
  277.         irpNew.RegisterCallback(this);
  278.         m_irp = irpNew;
  279.  
  280.         System.out.println("Registered IRemoteProcessCallback.");
  281.  
  282.         DeleteDebugKey();
  283.  
  284.         throw new ComSuccessException();
  285.     }
  286.  
  287.     // IRemoteProcessCallback methods
  288.  
  289.     public synchronized void ProcessDestroyEvent(IRemoteThread irth)
  290.     {
  291.         // Unregister process callback.
  292.  
  293.         System.out.println("Received IRemoteProcessCallback::ProcessDestroyEvent().");
  294.  
  295.         m_irp.Detach();
  296.         m_irp = null;
  297.  
  298.         System.out.println("Detached IRemoteProcessCallback from IRemoteProcess.");
  299.  
  300.         notify();
  301.  
  302.         throw new ComSuccessException();
  303.     }
  304.  
  305.     public void ClassLoadEvent(IRemoteThread irth, IRemoteClassField ircfClass)
  306.     {
  307.         String sClassName;
  308.  
  309.         System.out.println("Received IRemoteProcessCallback::ClassLoadEvent().");
  310.  
  311.         // Is this the class that a breakpoint is to be set on?
  312.  
  313.         sClassName = ((IRemoteField)ircfClass).GetName();
  314.  
  315.         if (sClassName.equals(sDebugClass))
  316.         {
  317.             IJavaEnumRemoteField ierf;
  318.             IRemoteField irf;
  319.  
  320.             System.out.println("Loaded class " + sClassName + " is being debugged.");
  321.  
  322.             // Yes.  Look for the method to set a breakpoint on.
  323.  
  324.             ierf = ((IRemoteContainerField)ircfClass).GetFields(FIELDKIND.FIELD_KIND_METHOD, 0, sDebugMethod);
  325.  
  326.             irf = ierf.GetNext();
  327.  
  328.             // Found the method.  Set a breakpoint.
  329.  
  330.             ((IRemoteMethodField)irf).SetBreakpoint(cnBreakpointPC);
  331.  
  332.             System.out.println("Set breakpoint on " + sDebugClass + "." + sDebugMethod + "()." + cnBreakpointPC + ".");
  333.         }
  334.  
  335.         throw new ComSuccessException();
  336.     }
  337.  
  338.     public void CodeBreakpointEvent(IRemoteThread irth)
  339.     {
  340.         IRemoteMethodField irmf;
  341.         IRemoteClassField ircf;
  342.  
  343.         // Clear the breakpoint.
  344.  
  345.         System.out.println("Received IRemoteProcessCallback::CodeBreakpointEvent().");
  346.  
  347.         System.out.println("Hit breakpoint at Hello.main().");
  348.  
  349.         // ((IRemoteMethodField)(irth.GetCurrentFrame().GetMethodObject().GetType())).ClearBreakpoint(cnBreakpointPC);
  350.  
  351.         irmf = (IRemoteMethodField)(irth.GetCurrentFrame().GetMethodObject().GetType());
  352.  
  353.         // Dump this method's bytecodes.
  354.  
  355.         DumpMethodBytes(irmf);
  356.  
  357.         // Dump this method's line number information.
  358.  
  359.         DumpMethodLineInfo(irmf);
  360.  
  361.         ircf = (IRemoteClassField)(irmf.GetContainer());
  362.  
  363.         // Dump constant pool item 5's bytes.
  364.  
  365.         DumpConstantPoolItem(ircf, 5);
  366.  
  367.         irmf.ClearBreakpoint(cnBreakpointPC);
  368.  
  369.         System.out.println("Cleared breakpoint.");
  370.  
  371.         throw new ComSuccessException();
  372.     }
  373.  
  374.     public void DebugStringEvent(IRemoteThread irth, String sDebugMsg)
  375.     {
  376.         System.out.println("Received IRemoteProcessCallback::DebugStringEvent().");
  377.  
  378.         throw new ComSuccessException();
  379.     }
  380.  
  381.     public void DataBreakpointEvent(IRemoteThread irth, IRemoteObject iro)
  382.     {
  383.         System.out.println("Received IRemoteProcessCallback::DataBreakpointEvent().");
  384.  
  385.         throw new ComSuccessException();
  386.     }
  387.  
  388.     public void ExceptionEvent(IRemoteThread irth, IRemoteClassField ircfException, int exceptionKind)
  389.     {
  390.         System.out.println("Received IRemoteProcessCallback::ExceptionEvent().");
  391.  
  392.         throw new ComSuccessException();
  393.     }
  394.  
  395.     public void StepEvent(IRemoteThread irth)
  396.     {
  397.         System.out.println("Received IRemoteProcessCallback::StepEvent().");
  398.  
  399.         throw new ComSuccessException();
  400.     }
  401.  
  402.     public void CanStopEvent(IRemoteThread irth)
  403.     {
  404.         System.out.println("Received IRemoteProcessCallback::CanStopEvent().");
  405.  
  406.         throw new ComSuccessException();
  407.     }
  408.  
  409.     public void BreakEvent(IRemoteThread irth)
  410.     {
  411.         System.out.println("Received IRemoteProcessCallback::BreakEvent().");
  412.  
  413.         throw new ComSuccessException();
  414.     }
  415.  
  416.     public void ThreadCreateEvent(IRemoteThread irth)
  417.     {
  418.         System.out.println("Received IRemoteProcessCallback::ThreadCreateEvent().");
  419.  
  420.         throw new ComSuccessException();
  421.     }
  422.  
  423.     public void ThreadDestroyEvent(IRemoteThread irth)
  424.     {
  425.         System.out.println("Received IRemoteProcessCallback::ThreadDestroyEvent().");
  426.  
  427.         throw new ComSuccessException();
  428.     }
  429.  
  430.     public void ThreadGroupCreateEvent(IRemoteThread irth, IRemoteThreadGroup irthg)
  431.     {
  432.         System.out.println("Received IRemoteProcessCallback::ThreadGroupCreateEvent().");
  433.  
  434.         throw new ComSuccessException();
  435.     }
  436.  
  437.     public void ThreadGroupDestroyEvent(IRemoteThread irth, IRemoteThreadGroup irthg)
  438.     {
  439.         System.out.println("Received IRemoteProcessCallback::ThreadGroupDestroyEvent().");
  440.  
  441.         throw new ComSuccessException();
  442.     }
  443.  
  444.     public void ClassUnloadEvent(IRemoteThread irth, IRemoteClassField ircfClass)
  445.     {
  446.         System.out.println("Received IRemoteProcessCallback::ClassUnloadEvent().");
  447.  
  448.         throw new ComSuccessException();
  449.     }
  450.  
  451.     public void TraceEvent(IRemoteThread irth)
  452.     {
  453.         System.out.println("Received IRemoteProcessCallback::TraceEvent().");
  454.  
  455.         throw new ComSuccessException();
  456.     }
  457.  
  458.     public void LoadCompleteEvent(IRemoteThread irth)
  459.     {
  460.         System.out.println("Received IRemoteProcessCallback::LoadCompleteEvent().");
  461.  
  462.         throw new ComSuccessException();
  463.     }
  464. };
  465.  
  466.