1472N/A * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A////////////////////////////////////////////////////////////////////// 0N/A// Exported "interface" for Java language-level interaction between // 0N/A// the SA and the VM. Note that the SA knows about the layout of // 0N/A// certain VM data structures and that knowledge is taken advantage // 0N/A// of in this code, although this interfaces with the VM via JVMDI. // 0N/A////////////////////////////////////////////////////////////////////// 0N/A ///////////////////////////////////// 0N/A // Events sent by the VM to the SA // 0N/A ///////////////////////////////////// 0N/A // Set by the SA when it attaches. Indicates that events should be 0N/A // posted via these exported variables, and that the VM should wait 0N/A // for those events to be acknowledged by the SA (via its setting 0N/A // saEventPending to 0). 0N/A // Set to nonzero value by the VM when an event has been posted; set 0N/A // back to 0 by the SA when it has processed that event. 0N/A // Breakpoint events 0N/A /////////////////////////////////////// 0N/A // Commands sent by the SA to the VM // 0N/A /////////////////////////////////////// 0N/A // SA sets this to a nonzero value when it is requesting a command 0N/A // to be processed; VM sets it back to 0 when the command has been 0N/A // SA sets this to one of the manifest constants above to indicate 0N/A // the kind of command to be executed 0N/A // VM sets this to 0 if the last command succeeded or a nonzero 0N/A // value if it failed 0N/A // If last command failed, this buffer will contain a descriptive 0N/A // Toggling of breakpoint command arguments. 0N/A // Originally there were separate set/clear breakpoint commands 0N/A // taking a class name, method name and signature, and the iteration 0N/A // through the debug information was done in the SA. It turns out 0N/A // that doing this work in the target VM is significantly faster, 0N/A // and since interactivity when setting and clearing breakpoints is 0N/A // important, the solution which resulted in more C/C++ code was used. 0N/A // Package name ('/' as separator instead of '.') 0N/A // Output back to SA: indicator whether the last failure of a 0N/A // breakpoint toggle command was really an error or just a lack of 0N/A // debug information covering the requested line. 0 if not error. 0N/A // Valid only if saCmdResult != 0. 0N/A // Output back to SA: resulting line number at which the breakpoint 0N/A // was set or cleared (valid only if saCmdResult == 0) 0N/A // Output back to SA: resulting byte code index at which the 0N/A // breakpoint was set or cleared (valid only if saCmdResult == 0) 0N/A // Output back to SA: indicator whether the breakpoint operation 0N/A // resulted in a set or cleared breakpoint; nonzero if set, zero if 0N/A // cleared (valid only if saCmdResult == 0) 0N/A // Output back to SA: method name the breakpoint was set in (valid 0N/A // only if saCmdResult == 0) 0N/A // Output back to SA: method signature (JNI style) the breakpoint 0N/A // was set in (valid only if saCmdResult == 0) 0N/A// This fills in the command result error message, sets the command 0N/A// result to -1, and clears the pending command flag 0N/A // Ensure that '/' is the next character if non-empty package name 0N/A // Ensure that there are no more trailing slashes 0N/A // We implement this by getting all of the threads and calling 0N/A // SuspendThread on each one, except for the thread object 0N/A // corresponding to this thread. Each thread for which the call 0N/A // succeeded (i.e., did not return JVMDI_ERROR_INVALID_THREAD) 0N/A // is added to a list which is remembered for later resumption. 0N/A // Note that this currently has race conditions since a thread 0N/A // might be started after we call GetAllThreads and since a 0N/A // thread for which we got an error earlier might be resumed by 0N/A // the VM while we are busy suspending other threads. We could 0N/A // solve this by looping until there are no more threads we can 0N/A // suspend, but a more robust and scalable solution is to add 0N/A // this functionality to the JVMDI interface (i.e., 0N/A // "suspendAll"). Probably need to provide an exclude list for 0N/A // Remember this thread and do not free it 0N/A // FIXME: stop, resume all threads, report error 0N/A // Suspension is complete 0N/A // Search line number info for all loaded classes 0N/A // Got a match. Now see whether the package name of the class also matches 0N/A // Iterate through all methods 0N/A // Look for line number greater than or equal to requested line 0N/A // Really toggle this breakpoint 0N/A reportErrorToSA(
"Unexpected error %d while setting or clearing breakpoint at bci %d, line %d",
0N/A // Successful command execution 0N/A stop(
"Error while starting Serviceability Agent " 0N/A "command thread: could not get JNI environment");
0N/A // Create event lock 0N/A stop(
"Unable to create Serviceability Agent's event lock");
0N/A // Start thread which receives commands from the SA. 0N/A // Allocate thread object 0N/A // Remember which thread this is 0N/A // OK, initialization is done 0N/A // saEventPending = 1;