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