/** * Processes an INSTRUMENT_CLASS command sent by the agent. * * @param aInstrumenter The instrumenter that will do the BCI of the class * @param aInputStream Input stream connected to the agent * @param aOutputStream Output stream connected to the agent */ public void processInstrumentClassCommand( IInstrumenter aInstrumenter, DataInputStream aInputStream, DataOutputStream aOutputStream) throws IOException { String theClassName = aInputStream.readUTF(); int theLength = aInputStream.readInt(); byte[] theBytecode = new byte[theLength]; aInputStream.readFully(theBytecode); System.out.println("Instrumenting " + theClassName + "... "); InstrumentedClass theInstrumentedClass = null; Throwable theError = null; try { theInstrumentedClass = aInstrumenter.instrumentClass(theClassName, theBytecode, itsUseJava14); } catch (Throwable e) { System.err.println("Error during instrumentation, reporting to client: "); e.printStackTrace(); theError = e; } if (theInstrumentedClass != null) { System.out.println("Instrumented (size: " + theInstrumentedClass.bytecode.length + ")"); if (itsStoreClassesDir != null) { File theFile = new File(itsStoreClassesDir, theClassName + ".class"); theFile.getParentFile().mkdirs(); theFile.createNewFile(); FileOutputStream theFileOutputStream = new FileOutputStream(theFile); theFileOutputStream.write(theInstrumentedClass.bytecode); theFileOutputStream.flush(); theFileOutputStream.close(); System.out.println("Written class to " + theFile); } // Write out instrumented bytecode aOutputStream.writeInt(theInstrumentedClass.bytecode.length); aOutputStream.write(theInstrumentedClass.bytecode); // Write out traced method ids System.out.println( "Sending " + theInstrumentedClass.tracedMethods.size() + " traced methods."); aOutputStream.writeInt(theInstrumentedClass.tracedMethods.size()); for (int theId : theInstrumentedClass.tracedMethods) { aOutputStream.writeInt(theId); } } else if (theError != null) { aOutputStream.writeInt(-1); StringWriter theStringWriter = new StringWriter(); PrintWriter thePrintWriter = new PrintWriter(theStringWriter); thePrintWriter.println( "Error occurred in database process while instrumenting " + theClassName + ":"); theError.printStackTrace(thePrintWriter); aOutputStream.writeUTF(theStringWriter.toString()); } else { System.out.println("Not instrumented"); aOutputStream.writeInt(0); } aOutputStream.flush(); }
/** * Sends configuration data to the agent. This method is called once at the beginning of the * connection. */ private void processConfig(DataInputStream aInputStream, DataOutputStream aOutputStream) throws IOException { DataInputStream theInStream = new DataInputStream(aInputStream); DataOutputStream theOutStream = new DataOutputStream(aOutputStream); // Read host name itsHostName = theInStream.readUTF(); System.out.println("[NativeAgentPeer] Received host name: '" + itsHostName + "'"); itsUseJava14 = theInStream.readByte() != 0; // Send host id theOutStream.writeInt(itsHostId); // Send remaining config boolean theSkipCoreClasses = itsConfig.get(TODConfig.AGENT_SKIP_CORE_CLASSE); theOutStream.writeByte(SET_SKIP_CORE_CLASSES); theOutStream.writeByte(theSkipCoreClasses ? 1 : 0); boolean theCaptureExceptions = itsConfig.get(TODConfig.AGENT_CAPTURE_EXCEPTIONS); theOutStream.writeByte(SET_CAPTURE_EXCEPTIONS); theOutStream.writeByte(theCaptureExceptions ? 1 : 0); int theHostBits = AgentConfig.HOST_BITS; theOutStream.writeByte(SET_HOST_BITS); theOutStream.writeByte(theHostBits); String theWorkingSet = itsConfig.get(TODConfig.SCOPE_TRACE_FILTER); theOutStream.writeByte(SET_WORKINGSET); theOutStream.writeUTF(theWorkingSet); theOutStream.writeByte(SET_STRUCTDB_ID); theOutStream.writeUTF(itsStructureDatabaseId); // Special cases working set StringBuilder theSCWS = new StringBuilder("["); for (String theName : itsInstrumenter.getSpecialCaseClasses()) { theSCWS.append(" +"); theSCWS.append(theName); } theSCWS.append(']'); theOutStream.writeByte(SET_SPECIALCASE_WORKINGSET); theOutStream.writeUTF(theSCWS.toString()); // Finish theOutStream.writeByte(CONFIG_DONE); theOutStream.flush(); }
/** * Processes a REGISTER_CLASS command sent by the agent. * * @param aInstrumenter The instrumenter that will register the class * @param aInputStream Input stream connected to the agent */ public void processRegisterClassCommand(IInstrumenter aInstrumenter, DataInputStream aInputStream) throws IOException { String theClassName = aInputStream.readUTF(); int theLength = aInputStream.readInt(); byte[] theBytecode = new byte[theLength]; aInputStream.readFully(theBytecode); Utils.println("Registering %s [%d]...", theClassName, theLength); InstrumentedClass theInstrumentedClass = null; try { theInstrumentedClass = aInstrumenter.instrumentClass(theClassName, theBytecode, itsUseJava14); if (theInstrumentedClass != null) throw new RuntimeException("Class should not be instrumented: " + theClassName); } catch (Exception e) { System.err.println("Error during registration: "); e.printStackTrace(); } }