You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/07/23 18:18:30 UTC
svn commit: r558788 [1/2] - in /harmony/enhanced/jdktools/trunk/modules/jpda:
src/main/native/jdwp/common/agent/core/
src/main/native/jdwp/common/transport/dt_socket/
src/main/native/jdwp/unix/agent/ src/main/native/jdwp/unix/agent/core/
src/main/nativ...
Author: gshimansky
Date: Mon Jul 23 09:18:27 2007
New Revision: 558788
URL: http://svn.apache.org/viewvc?view=rev&rev=558788
Log:
Applied patch from HARMONY-2892
[jdktools][jdwp] Support on-demand debugger attach in JDWP agent
Added:
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.cpp (with props)
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.h (with props)
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/LaunchedDebugger.java (with props)
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthowDebuggerLaunchDebuggee.java (with props)
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthrowDebuggerLaunchTest.java (with props)
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthrowLaunchDebugger001.java (with props)
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthrowLaunchDebugger002.java (with props)
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/share/JDWPUnitDebuggeeProcessWrapper.java (with props)
Modified:
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/Agent.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentBase.h
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentEnv.h
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentException.h
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.h
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.h
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.h
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/transport/dt_socket/SocketTransport.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/core/TransportManager_pd.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/makefile
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/transport/makefile
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/core/TransportManager_pd.cpp
harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/makefile
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/TestOptions.java
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/share/JDWPRawTestCase.java
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/share/JDWPSyncTestCase.java
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/share/JDWPTestCase.java
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/share/JDWPUnitDebuggeeWrapper.java
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/share/JPDADebuggeeSynchronizer.java
harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/share/SyncDebuggee.java
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/Agent.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/Agent.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/Agent.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/Agent.cpp Mon Jul 23 09:18:27 2007
@@ -41,6 +41,7 @@
#include "TransportManager.h"
#include "PacketDispatcher.h"
#include "EventDispatcher.h"
+#include "AgentManager.h"
using namespace jdwp;
@@ -103,50 +104,6 @@
);
}
-static void InitAgent(jvmtiEnv *jvmti, JNIEnv *jni)
-{
- JDWP_TRACE_ENTRY("InitAgent(" << jvmti << "," << jni << ")");
-
- JDWP_TRACE_PROG("InitAgent: init and start all modules");
-
- //currentSessionID = 0;
-
- try {
- AgentBase::SetIsDead(false);
- AgentBase::GetClassManager().Init(jni);
- AgentBase::GetObjectManager().Init(jni);
- AgentBase::GetThreadManager().Init(jni);
- AgentBase::GetRequestManager().Init(jni);
- AgentBase::GetEventDispatcher().Init(jni);
- AgentBase::GetPacketDispatcher().Init(jni);
-
- char* javaLibraryPath = 0;
- jvmtiError err;
- JVMTI_TRACE(err,
- jvmti->GetSystemProperty("java.library.path", &javaLibraryPath));
- if (err != JVMTI_ERROR_NONE) {
- JDWP_INFO("Unable to get system property: java.library.path")
- }
- JvmtiAutoFree afv(javaLibraryPath);
- AgentBase::GetTransportManager().Init(
- AgentBase::GetOptionParser().GetTransport(),
- javaLibraryPath);
-
- AgentBase::GetTransportManager().PrepareConnection(
- AgentBase::GetOptionParser().GetAddress(),
- AgentBase::GetOptionParser().GetServer(),
- AgentBase::GetOptionParser().GetTimeout(),
- AgentBase::GetOptionParser().GetTimeout()
- );
-
- AgentBase::GetEventDispatcher().Start(jni);
- AgentBase::GetPacketDispatcher().Start(jni);
- } catch (AgentException& e) {
- JDWP_INFO("JDWP error: " << e.what() << " [" << e.ErrCode() << "]");
- jni->FatalError("Unable to initialize agent");
- }
-}
-
//-----------------------------------------------------------------------------
// event callbacks
//-----------------------------------------------------------------------------
@@ -159,10 +116,20 @@
jint ver = jni->GetVersion();
JDWP_LOG("JNI version: 0x" << hex << ver);
- InitAgent(jvmti, jni);
- RequestManager::HandleVMInit(jvmti, jni, thread);
+ // initialize agent
+ AgentBase::GetAgentManager().Init(jvmti, jni);
+
+ // if options onthrow or onuncaught are set, defer starting agent and enable notification of EXCEPTION event
+ if (AgentBase::GetOptionParser().GetOnthrow() || AgentBase::GetOptionParser().GetOnuncaught()) {
+ AgentBase::GetAgentManager().EnableInitialExceptionCatch(jvmti, jni);
+ } else {
+ AgentBase::GetAgentManager().Start(jvmti, jni);
+ RequestManager::HandleVMInit(jvmti, jni, thread);
+ }
+ } catch (TransportException& e) {
+ JDWP_DIE("JDWP transport error in VM_INIT: " << e.TransportErrorMessage() << " [" << e.ErrCode() << "]");
} catch (AgentException& e) {
- JDWP_INFO("JDWP error in VM_INIT: " << e.what() << " [" << e.ErrCode() << "]");
+ JDWP_DIE("JDWP error in VM_INIT: " << e.what() << " [" << e.ErrCode() << "]");
}
}
@@ -170,13 +137,16 @@
VMDeath(jvmtiEnv *jvmti, JNIEnv *jni)
{
try {
- // don't print entry trace message after shutdown
- {
+ if (AgentBase::GetAgentManager().IsStarted()) {
+ // don't print entry trace message after cleaning agent
JDWP_TRACE_ENTRY("VMDeath(" << jvmti << ',' << jni << ')');
+
RequestManager::HandleVMDeath(jvmti, jni);
+ AgentBase::SetIsDead(true);
+
+ AgentBase::GetAgentManager().Stop(jni);
}
- AgentBase::SetIsDead(true);
- AgentBase::GetPacketDispatcher().ShutdownAll(jni);
+ AgentBase::GetAgentManager().Clean(jni);
} catch (AgentException& e) {
JDWP_INFO("JDWP error in VM_DEATH: " << e.what() << " [" << e.ErrCode() << "]");
}
@@ -324,6 +294,7 @@
env.transportManager = new TransportManager();
env.packetDispatcher = new PacketDispatcher();
env.eventDispatcher = new EventDispatcher();
+ env.agentManager = new AgentManager();
} catch (IllegalArgumentException&) {
JDWP_INFO("JDWP error: Bad agent options: " << options);
delete env.optionParser;
@@ -488,5 +459,6 @@
delete &AgentBase::GetObjectManager();
delete &AgentBase::GetClassManager();
delete &AgentBase::GetOptionParser();
+ delete &AgentBase::GetAgentManager();
}
}
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentBase.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentBase.h?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentBase.h (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentBase.h Mon Jul 23 09:18:27 2007
@@ -224,6 +224,14 @@
}
/**
+ * Gets the agent-manager reference from the agent base.
+ */
+ static AgentManager& GetAgentManager() throw() {
+ CHECK_ENV_PTR(m_agentEnv, agentManager);
+ return *m_agentEnv->agentManager;
+ }
+
+ /**
* Gets the pointer to JVMTI environment from the agent base.
*/
static jvmtiEnv* GetJvmtiEnv() throw() {
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentEnv.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentEnv.h?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentEnv.h (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentEnv.h Mon Jul 23 09:18:27 2007
@@ -46,6 +46,7 @@
class PacketDispatcher;
class EventDispatcher;
class RequestManager;
+ class AgentManager;
/**
* Agent-environment structure containing all objects participating in
@@ -53,6 +54,7 @@
*/
struct AgentEnv {
+ AgentManager *agentManager;
MemoryManager *memoryManager;
LogManager *logManager;
OptionParser *optionParser;
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentException.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentException.h?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentException.h (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentException.h Mon Jul 23 09:18:27 2007
@@ -31,6 +31,7 @@
#define _AGENT_EXCEPTION_H_
#include <exception>
+#include <sstream>
#include "jdwp.h"
#include "jvmti.h"
@@ -202,30 +203,40 @@
* @param transportError - transport error code
*/
TransportException(jdwpError err = JDWP_ERROR_TRANSPORT_INIT,
- jdwpTransportError transportError = JDWPTRANSPORT_ERROR_NONE)
+ jdwpTransportError transportError = JDWPTRANSPORT_ERROR_NONE,
+ const char* message = 0)
throw() : AgentException(err)
{
this->m_transportError = transportError;
+ this->m_message = message;
}
/**
- * Returns transport-error code.
+ * Returns transport error code.
*/
jdwpTransportError TransportErrorCode() const throw() {
return m_transportError;
}
/**
- * Returns the given exception name.
+ * Returns transport error message.
+ */
+ const char* TransportErrorMessage() const throw() {
+ return m_message;
+ }
+
+ /**
+ * Returns the given exception info.
*/
const char* what() const throw() {
- return "TransportException";
+ return (m_message == 0 ? "TransportException" : m_message);
}
private:
jdwpTransportError m_transportError;
+ const char* m_message;
};
-}
+};
#endif // _AGENT_EXCEPTION_H_
Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.cpp?view=auto&rev=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.cpp (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.cpp Mon Jul 23 09:18:27 2007
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksander V. Budniy
+ * @version $Revision: 1.10.2.1 $
+ */
+
+#include "AgentManager.h"
+#include "ClassManager.h"
+#include "ObjectManager.h"
+#include "OptionParser.h"
+#include "ThreadManager.h"
+#include "RequestManager.h"
+#include "TransportManager.h"
+#include "PacketDispatcher.h"
+#include "EventDispatcher.h"
+
+using namespace jdwp;
+
+void AgentManager::Init(jvmtiEnv *jvmti, JNIEnv *jni) throw (AgentException)
+{
+ JDWP_TRACE_ENTRY("Init(" << jvmti << "," << jni << ")");
+
+ JDWP_TRACE_PROG("Init: init agent modules and load transport");
+
+ AgentBase::SetIsDead(false);
+ AgentBase::GetClassManager().Init(jni);
+ AgentBase::GetObjectManager().Init(jni);
+ AgentBase::GetThreadManager().Init(jni);
+ AgentBase::GetRequestManager().Init(jni);
+ AgentBase::GetEventDispatcher().Init(jni);
+ AgentBase::GetPacketDispatcher().Init(jni);
+
+ char* javaLibraryPath = 0;
+ jvmtiError err;
+ JVMTI_TRACE(err,
+ jvmti->GetSystemProperty("java.library.path", &javaLibraryPath));
+ if (err != JVMTI_ERROR_NONE) {
+ JDWP_INFO("Unable to get system property: java.library.path")
+ }
+
+ JvmtiAutoFree afv(javaLibraryPath);
+ AgentBase::GetTransportManager().Init(
+ AgentBase::GetOptionParser().GetTransport(),
+ javaLibraryPath);
+
+}
+
+void AgentManager::Start(jvmtiEnv *jvmti, JNIEnv *jni) throw (AgentException)
+{
+ JDWP_TRACE_ENTRY("Start(" << jvmti << "," << jni << ")");
+
+ JDWP_TRACE_PROG("Start: prepare connection and start all agent threads");
+
+ // prepare transport connection
+ AgentBase::GetTransportManager().PrepareConnection(
+ AgentBase::GetOptionParser().GetAddress(),
+ AgentBase::GetOptionParser().GetServer(),
+ AgentBase::GetOptionParser().GetTimeout(),
+ AgentBase::GetOptionParser().GetTimeout()
+ );
+
+ // launch debugger if required and disable initial handling of EXCEPTION event
+ const char* launch = AgentBase::GetOptionParser().GetLaunch();
+ if (launch != 0) {
+ AgentBase::GetTransportManager().Launch(launch);
+ DisableInitialExceptionCatch(jvmti, jni);
+ }
+
+ // start agent threads
+ AgentBase::GetEventDispatcher().Start(jni);
+ AgentBase::GetPacketDispatcher().Start(jni);
+ SetStarted(true);
+}
+
+void
+AgentManager::Stop(JNIEnv *jni) throw(AgentException)
+{
+ JDWP_TRACE_ENTRY("Stop(" << jni << ")");
+
+ // stop PacketDispatcher and EventDispatcher threads, and reset all modules
+ JDWP_TRACE_PROG("Stop: stop all agent threads");
+ GetPacketDispatcher().Stop(jni);
+}
+
+void
+AgentManager::Clean(JNIEnv *jni) throw(AgentException)
+{
+ // trace entry before cleaning LogManager
+ {
+ JDWP_TRACE_ENTRY("Clean(" << jni << ")");
+
+ // clean all modules
+ JDWP_TRACE_PROG("Clean: clean agent modules");
+ GetPacketDispatcher().Clean(jni);
+ GetThreadManager().Clean(jni);
+ GetRequestManager().Clean(jni);
+ GetEventDispatcher().Clean(jni);
+ GetObjectManager().Clean(jni);
+ GetClassManager().Clean(jni);
+ }
+
+ // clean LogManager and close log
+ GetLogManager().Clean();
+}
+
+void AgentManager::EnableInitialExceptionCatch(jvmtiEnv *jvmti, JNIEnv *jni) throw (AgentException)
+{
+ JDWP_TRACE_PROG("EnableInitialExceptionCatch");
+
+ jvmtiError err;
+ JVMTI_TRACE(err, jvmti->SetEventNotificationMode(
+ JVMTI_ENABLE , JVMTI_EVENT_EXCEPTION, 0));
+ if (err != JVMTI_ERROR_NONE) {
+ throw AgentException(err);
+ }
+}
+
+void AgentManager::DisableInitialExceptionCatch(jvmtiEnv *jvmti, JNIEnv *jni) throw (AgentException)
+{
+ JDWP_TRACE_PROG("DisableInitialExceptionCatch");
+
+ jvmtiError err;
+ JVMTI_TRACE(err, jvmti->SetEventNotificationMode(
+ JVMTI_DISABLE, JVMTI_EVENT_EXCEPTION, 0));
+ if (err != JVMTI_ERROR_NONE) {
+ throw AgentException(err);
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.h?view=auto&rev=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.h (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.h Mon Jul 23 09:18:27 2007
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * ClassManager.h
+ *
+ * Provides access to certain standard Java classes.
+ */
+
+/**
+ * @author Aleksander V. Budniy
+ * @version $Revision: 1.10.2.1 $
+ */
+
+/**
+ * @file
+ * ClassManager.h
+ *
+ * Provides initialization of JDWP agent.
+ */
+
+#ifndef _AGENT_MANAGER_H_
+#define _AGENT_MANAGER_H_
+
+#include "jni.h"
+#include "jvmti.h"
+#include "AgentBase.h"
+
+namespace jdwp {
+
+ /**
+ * This class provides initialization of JDWP agent.
+ */
+ class AgentManager : public AgentBase {
+
+ public :
+
+ /**
+ * A constructor.
+ */
+ AgentManager() throw() {
+ m_isStarted = false;
+ }
+
+ /**
+ * A destructor.
+ */
+ ~AgentManager() throw () {
+ }
+
+ /**
+ * Initializes all agent modules.
+ */
+ void Init(jvmtiEnv *jvmti, JNIEnv *jni) throw (AgentException);
+
+ /**
+ * Start all agent threads.
+ */
+ void Start(jvmtiEnv *jvmti, JNIEnv *jni) throw (AgentException);
+
+ /**
+ * Stop all agent threads.
+ */
+ void Stop(JNIEnv *jni) throw (AgentException);
+
+ /**
+ * Clean all agent modules.
+ */
+ void Clean(JNIEnv *jni) throw (AgentException);
+
+ /*
+ * Returns started status of this agent.
+ */
+ bool IsStarted() throw() {
+ return m_isStarted;
+ }
+
+ /*
+ * Sets started status of this agent.
+ */
+ void SetStarted(bool isStarted) throw() {
+ m_isStarted = isStarted;
+ }
+
+ /**
+ * Enables catching initial EXCEPTION event to launch debugger.
+ */
+ void EnableInitialExceptionCatch(jvmtiEnv *jvmti, JNIEnv *jni) throw (AgentException);
+
+ /**
+ * Disables catching initial EXCEPTION event to launch debugger.
+ */
+ void DisableInitialExceptionCatch(jvmtiEnv *jvmti, JNIEnv *jni) throw (AgentException);
+
+ private :
+
+ bool volatile m_isStarted;
+
+ }; //class AgentManager
+
+}// namespace jdwp
+
+#endif //_AGENT_MANAGER_H_
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/AgentManager.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.cpp Mon Jul 23 09:18:27 2007
@@ -47,6 +47,9 @@
m_log = 0;
m_kindFilter = 0;
m_srcFilter = 0;
+ m_onuncaught = false;
+ m_onthrow = 0;
+ m_launch = 0;
}
bool OptionParser::AsciiToBool(const char *str) throw(IllegalArgumentException)
@@ -75,12 +78,13 @@
for (i = 0; i < len; i++) {
if (str[i] == ',') {
m_optionCount++;
- } else if (str[i] == '"') {
+ } else if (str[i] == '"' || str[i] == '\'') {
+ char quote = str[i];
if (i > 0 && str[i-1] != '=') {
throw IllegalArgumentException();
}
i++;
- while (i < len && str[i] != '"') {
+ while (i < len && str[i] != quote) {
i++;
}
if (i+1 < len && str[i+1] != ',') {
@@ -100,20 +104,24 @@
m_options[0].name = m_optionString;
m_options[0].value = "";
k = 0;
+ bool waitEndOfOption = false;
for (i = 0; i < len && k < m_optionCount; i++) {
- if (m_optionString[i] == '=') {
+ if ((m_optionString[i] == '=') && (!waitEndOfOption)) {
+ waitEndOfOption = true;
m_optionString[i] = '\0';
m_options[k].value = &m_optionString[i+1];
} else if (m_optionString[i] == ',') {
+ waitEndOfOption = false;
m_optionString[i] = '\0';
k++;
m_options[k].name = &m_optionString[i+1];
m_options[k].value = "";
- } else if (m_optionString[i] == '"') {
+ } else if (m_optionString[i] == '"' || m_optionString[i] == '\'') {
+ char quote = m_optionString[i];
m_optionString[i] = '\0';
m_options[k].value = &m_optionString[i+1];
i++;
- while (i < len && m_optionString[i] != '"') {
+ while (i < len && m_optionString[i] != quote) {
i++;
}
if (i < len) {
@@ -133,6 +141,12 @@
m_suspend = AsciiToBool(m_options[k].value);
} else if (strcmp("server", m_options[k].name) == 0) {
m_server = AsciiToBool(m_options[k].value);
+ } else if (strcmp("launch", m_options[k].name) == 0) {
+ m_launch = m_options[k].value;
+ } else if (strcmp("onuncaught", m_options[k].name) == 0) {
+ m_onuncaught = AsciiToBool(m_options[k].value);
+ } else if (strcmp("onthrow", m_options[k].name) == 0) {
+ m_onthrow = m_options[k].value;
} else if (strcmp("help", m_options[k].name) == 0) {
m_help = true;
#ifndef NDEBUG
@@ -143,6 +157,12 @@
} else if (strcmp("src", m_options[k].name) == 0) {
m_srcFilter = m_options[k].value;
#endif // NDEBUG
+ }
+ }
+ if ((m_onthrow != 0) || (m_onuncaught != 0)) {
+ if (m_launch == 0) {
+ JDWP_ERROR("Specify launch=<command line> when using onthrow or onuncaught option");
+ throw IllegalArgumentException();
}
}
}
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.h?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.h (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/OptionParser.h Mon Jul 23 09:18:27 2007
@@ -120,6 +120,15 @@
}
/**
+ * Returns a value for the agent's <code>onuncaught</code> option.
+ *
+ * @return Boolean.
+ */
+ bool GetOnuncaught() const throw() {
+ return m_onuncaught;
+ }
+
+ /**
* Returns a time-out value for transport operations.
*
* @return Java long value.
@@ -173,6 +182,24 @@
return m_srcFilter;
}
+ /**
+ * Returns a value for the agent's <code>onthrow</code> option.
+ *
+ * @return Zero-terminated string.
+ */
+ const char *GetOnthrow() const throw() {
+ return m_onthrow;
+ }
+
+ /**
+ * Returns a value for the agent's <code>launch</code> option.
+ *
+ * @return Zero-terminated string.
+ */
+ const char *GetLaunch() const throw() {
+ return m_launch;
+ }
+
private:
/**
@@ -199,12 +226,15 @@
bool m_help;
bool m_suspend;
bool m_server;
+ bool m_onuncaught;
jlong m_timeout;
const char *m_transport;
const char *m_address;
const char *m_log;
const char *m_kindFilter;
const char *m_srcFilter;
+ const char *m_launch;
+ const char *m_onthrow;
};
} // namespace jdwp
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.cpp Mon Jul 23 09:18:27 2007
@@ -228,6 +228,13 @@
// cause thread loop to break
m_isProcessed = false;
+ // close transport first, but not while executing current command
+ JDWP_TRACE_PROG("Stop: close agent connection");
+ if (m_executionMonitor != 0) {
+ MonitorAutoLock lock(m_executionMonitor JDWP_FILE_LINE);
+ GetTransportManager().Clean();
+ }
+
// wait for loop finished and EventDispatcher is also stopped
{
MonitorAutoLock lock(m_completionMonitor JDWP_FILE_LINE);
@@ -289,39 +296,6 @@
GetObjectManager().Reset(jni);
}
}
-
-void
-PacketDispatcher::ShutdownAll(JNIEnv *jni) throw(AgentException)
-{
- // trace entry before cleaning LogManager
- {
- JDWP_TRACE_ENTRY("ShutdownAll(" << jni << ")");
-
- // close transport first, but not while executing current command
- JDWP_TRACE_PROG("ShutdownAll: close agent connection");
- if (m_executionMonitor != 0) {
- MonitorAutoLock lock(m_executionMonitor JDWP_FILE_LINE);
- GetTransportManager().Clean();
- }
-
- // stop PacketDispatcher and EventDispatcher threads, and reset all modules
- JDWP_TRACE_PROG("ShutdownAll: stop agent threads");
- GetPacketDispatcher().Stop(jni);
-
- // clean all modules
- JDWP_TRACE_PROG("ShutdownAll: clean agent modules");
- GetPacketDispatcher().Clean(jni);
- GetThreadManager().Clean(jni);
- GetRequestManager().Clean(jni);
- GetEventDispatcher().Clean(jni);
- GetObjectManager().Clean(jni);
- GetClassManager().Clean(jni);
- }
-
- // clean LogManager and close log
- GetLogManager().Clean();
-}
-
//-----------------------------------------------------------------------------
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.h?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.h (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/PacketDispatcher.h Mon Jul 23 09:18:27 2007
@@ -128,7 +128,7 @@
*
* @exception If any error occurs, <code>AgentException</code> is thrown.
*/
- void ShutdownAll(JNIEnv *jni) throw(AgentException);
+// void ShutdownAll(JNIEnv *jni) throw(AgentException);
/**
* Determines if the <code>PacketDispatcher</code> object is already
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/RequestManager.cpp Mon Jul 23 09:18:27 2007
@@ -28,6 +28,7 @@
#include "ClassManager.h"
#include "OptionParser.h"
#include "Log.h"
+#include "AgentManager.h"
using namespace jdwp;
@@ -925,13 +926,84 @@
<< ',' << method << ',' << location
<< ',' << exception << ',' << catch_method << ',' << catch_location << ')');
- // must be non-agent thread
- if (GetThreadManager().IsAgentThread(jni, thread)) {
- return;
- }
-
try {
jvmtiError err;
+ jclass exceptionClass = 0;
+ AgentEventRequest* exceptionRequest = 0;
+
+ // if agent was not initialized and this exception is expected, initialize agent
+ if (!GetAgentManager().IsStarted()) {
+ JDWP_TRACE_PROG("HandleException: initial exception cought");
+
+ // if invocation option onuncaught=y is set, check that exception is uncaught, otherwise return
+ if (GetOptionParser().GetOnuncaught() != 0) {
+ if (catch_location != 0) {
+ JDWP_TRACE_PROG("HandleException: ignore cougth exception");
+ return;
+ }
+ }
+
+ // if invocation option onthrow=y is set, check that exception class is expected, otherwise return
+ if (GetOptionParser().GetOnthrow() != 0) {
+
+ char* expectedExceptionName = const_cast<char*>(GetOptionParser().GetOnthrow());
+ if (expectedExceptionName != 0) {
+
+ char* exceptionSignature = 0;
+ exceptionClass = jni->GetObjectClass(exception);
+
+ JVMTI_TRACE(err, jvmti->GetClassSignature(exceptionClass, &exceptionSignature, 0));
+ if (err != JVMTI_ERROR_NONE) {
+ throw AgentException(err);
+ }
+ JvmtiAutoFree jafSignature(exceptionSignature);
+
+ char* exceptionName = GetClassManager().GetClassName(exceptionSignature);
+ JvmtiAutoFree jafName(exceptionName);
+
+ JDWP_TRACE_PROG("HandleException: exception: class=" << exceptionName
+ << ", signature=" << exceptionSignature);
+
+ // compare exception class taking into account similar '/' and '.' delimiters
+ int i;
+ for (i = 0; ; i++) {
+ if (expectedExceptionName[i] != exceptionName[i]) {
+ if ((expectedExceptionName[i] == '.' && exceptionName[i] == '/')
+ || (expectedExceptionName[i] == '/' && exceptionName[i] == '.')) {
+ continue;
+ }
+ // ignore not matched exception
+ return;
+ }
+ if (expectedExceptionName[i] == '\0') {
+ // matched exception found
+ break;
+ }
+ }
+ }
+ }
+
+ // disable catching initial exception and start agent
+ JDWP_TRACE_PROG("HandleException: start agent");
+ GetAgentManager().DisableInitialExceptionCatch(jvmti, jni);
+ GetAgentManager().Start(jvmti, jni);
+
+ // check if VM should be suspended on initial EXCEPTION event
+ bool needSuspend = GetOptionParser().GetSuspend();
+ if (needSuspend) {
+ // add internal EXCEPTION request
+ exceptionRequest = new AgentEventRequest(JDWP_EVENT_EXCEPTION, JDWP_SUSPEND_ALL);
+ GetRequestManager().AddInternalRequest(jni, exceptionRequest);
+ } else {
+ return;
+ }
+ }
+
+ // must be non-agent thread
+ if (GetThreadManager().IsAgentThread(jni, thread)) {
+ return;
+ }
+
EventInfo eInfo;
memset(&eInfo, 0, sizeof(eInfo));
eInfo.kind = JDWP_EVENT_EXCEPTION;
@@ -952,7 +1024,11 @@
throw AgentException(err);
}
- eInfo.auxClass = jni->GetObjectClass(exception);
+ if (exceptionClass != 0) {
+ eInfo.auxClass = exceptionClass;
+ } else {
+ eInfo.auxClass = jni->GetObjectClass(exception);
+ }
JDWP_ASSERT(eInfo.auxClass != 0);
if (catch_method != 0) {
@@ -1011,6 +1087,12 @@
JDWP_TRACE_EVENT("Exception: post set of " << eventCount << " events");
GetEventDispatcher().PostEventSet(jni, ec, JDWP_EVENT_EXCEPTION);
}
+ // delete internal EXCEPTION request
+ if (exceptionRequest != 0) {
+ GetRequestManager().DeleteRequest(jni, exceptionRequest);
+ }
+ /* JVMTI_TRACE(err, jvmti->SetEventNotificationMode(
+ JVMTI_ENABLE , JVMTI_EVENT_BREAKPOINT, thread));*/
} catch (AgentException& e) {
JDWP_INFO("JDWP error in EXCEPTION: " << e.what() << " [" << e.ErrCode() << "]");
}
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp Mon Jul 23 09:18:27 2007
@@ -243,13 +243,17 @@
jthread
ThreadManager::RunAgentThread(JNIEnv *jni, jvmtiStartFunction proc,
const void *arg, jint priority,
- const char *name) throw(AgentException)
+ const char *name, jthread thread)
+ throw(AgentException)
{
JDWP_TRACE_ENTRY("RunAgentThread(" << jni << ',' << proc
<< ',' << arg << ',' << priority
<< ',' << JDWP_CHECK_NULL(name) << ')');
- jthread thread = CreateAgentThread(jni, name);
+ if (thread == 0) {
+ thread = CreateAgentThread(jni, name);
+ }
+
jvmtiError err;
JVMTI_TRACE(err, GetJvmtiEnv()->RunAgentThread(thread, proc, arg, priority));
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h Mon Jul 23 09:18:27 2007
@@ -109,8 +109,10 @@
* @param priority - the priority of the started thread
* @param name - the default parameter; if defined, then the created
* thread has a specified name
+ * @param name - the default parameter; if defined, then the created
+ * thread is associated with this object
*
- * @return Returns the <code>jthread</code> object that holds executed
+ * @return Returns the <code>jthread</code> object associated with started
* thread.
*
* @exception OutOfMemoryException is thrown if the system
@@ -123,7 +125,8 @@
*/
jthread RunAgentThread(JNIEnv *jni, jvmtiStartFunction proc,
const void *arg, jint priority,
- const char *name = 0) throw(AgentException);
+ const char *name = 0,
+ jthread thread = 0) throw(AgentException);
/**
* Adds an information about the thread parameter into
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.cpp Mon Jul 23 09:18:27 2007
@@ -44,6 +44,7 @@
TransportManager::TransportManager() : AgentBase()
{
+ m_transportName = 0;
m_connectTimeout = 0;
m_handshakeTimeout = 0;
m_ConnectionPrepared = false;
@@ -52,6 +53,7 @@
m_env = 0;
m_isServer = true;
m_lastErrorMessage = 0;
+ m_isConnected = false;
} //TransportManager::TransportManager()
TransportManager::~TransportManager()
@@ -75,11 +77,13 @@
{
JDWP_TRACE_ENTRY("Init(" << JDWP_CHECK_NULL(transportName) << ',' << JDWP_CHECK_NULL(libPath) << ')');
- JDWP_TRACE_PROG("Init: transport name=" << JDWP_CHECK_NULL(transportName )
- << " libPath=" << JDWP_CHECK_NULL(libPath));
+ JDWP_TRACE_PROG("Init: transport=" << JDWP_CHECK_NULL(transportName )
+ << ", libPath=" << JDWP_CHECK_NULL(libPath));
JDWP_ASSERT(m_loadedLib == 0);
+ m_isConnected = false;
+ m_transportName = transportName;
const char* begin = libPath;
do {
const char* end = strchr(begin, pathSeparator);
@@ -112,7 +116,7 @@
m_lastErrorMessage = static_cast<char *>(GetMemoryManager().Allocate(length JDWP_FILE_LINE));
sprintf(m_lastErrorMessage, "Loading of %s failed", transportName);
JDWP_ERROR("Loading of " << transportName << " failed");
- throw TransportException(JDWP_ERROR_TRANSPORT_LOAD);
+ throw TransportException(JDWP_ERROR_TRANSPORT_LOAD, JDWPTRANSPORT_ERROR_NONE, m_lastErrorMessage);
}
jdwpTransport_OnLoad_t transportOnLoad = reinterpret_cast<jdwpTransport_OnLoad_t>
@@ -126,14 +130,14 @@
m_lastErrorMessage = static_cast<char *>(GetMemoryManager().Allocate(length JDWP_FILE_LINE));
sprintf(m_lastErrorMessage, "%s function not found in %s", onLoadDecFuncName, transportName);
JDWP_ERROR(onLoadDecFuncName << " function not found in " << transportName);
- throw TransportException();
+ throw TransportException(JDWP_ERROR_TRANSPORT_INIT, JDWPTRANSPORT_ERROR_NONE, m_lastErrorMessage);
}
jint res = (*transportOnLoad)(GetJavaVM(), &callback, JDWPTRANSPORT_VERSION_1_0, &m_env);
if (res == JNI_ENOMEM) {
if (m_lastErrorMessage != 0) {
GetMemoryManager().Free(m_lastErrorMessage JDWP_FILE_LINE);
}
- size_t length = strlen("Out of memeory");
+ size_t length = strlen("Out of memory");
m_lastErrorMessage = static_cast<char *>(GetMemoryManager().Allocate(length JDWP_FILE_LINE));
sprintf(m_lastErrorMessage, "Out of memeory");
throw TransportException(JDWP_ERROR_OUT_OF_MEMORY);
@@ -145,7 +149,7 @@
m_lastErrorMessage = static_cast<char *>(GetMemoryManager().Allocate(length JDWP_FILE_LINE));
sprintf(m_lastErrorMessage, "Invoking of %s failed", onLoadDecFuncName);
JDWP_ERROR("Invoking of " << onLoadDecFuncName << " failed");
- throw TransportException();
+ throw TransportException(JDWP_ERROR_TRANSPORT_INIT, JDWPTRANSPORT_ERROR_NONE, m_lastErrorMessage);
}
if (m_env == 0) {
if (m_lastErrorMessage != 0) {
@@ -155,7 +159,7 @@
m_lastErrorMessage = static_cast<char *>(GetMemoryManager().Allocate(length JDWP_FILE_LINE));
sprintf(m_lastErrorMessage, "Transport provided invalid environment");
JDWP_ERROR("Transport provided invalid environment");
- throw TransportException();
+ throw TransportException(JDWP_ERROR_TRANSPORT_INIT, JDWPTRANSPORT_ERROR_NONE, m_lastErrorMessage);
}
} // TransportManager::Init()
@@ -194,12 +198,10 @@
}
if (isServer) {
- char* actualAddress;
- err = m_env->StartListening(address, &actualAddress);
+ err = m_env->StartListening(address, &m_address);
CheckReturnStatus(err);
- JDWP_INFO("transport is listening on " << actualAddress);
- JDWP_TRACE_PROG("PrepareConnection: listening on " << actualAddress);
- AgentBase::GetMemoryManager().Free(actualAddress JDWP_FILE_LINE);
+ JDWP_INFO("transport is listening on " << m_address);
+ JDWP_TRACE_PROG("PrepareConnection: listening on " << m_address);
} else {
m_address = static_cast<char *>(GetMemoryManager().Allocate(strlen(address) + 1 JDWP_FILE_LINE));
strcpy(m_address, address);
@@ -212,6 +214,10 @@
void
TransportManager::Connect() throw(TransportException)
{
+ if (m_isConnected) {
+ return;
+ }
+
JDWP_TRACE_PROG("Connect: isServer=" << m_isServer);
JDWP_ASSERT(m_ConnectionPrepared);
jdwpTransportError err;
@@ -222,15 +228,19 @@
err = m_env->Attach(m_address, m_connectTimeout, m_handshakeTimeout);
CheckReturnStatus(err);
}
+ m_isConnected = true;
JDWP_TRACE_PROG("Connect: connection established");
} // TransportManager::Connect()
void
-TransportManager::Launch(const char* command) throw(TransportException)
+TransportManager::Launch(const char* command) throw(AgentException)
{
JDWP_TRACE_PROG("Launch: " << JDWP_CHECK_NULL(command));
JDWP_ASSERT(m_ConnectionPrepared);
- StartDebugger(command);
+ const char* extra_argv[2];
+ extra_argv[0] = m_transportName;
+ extra_argv[1] = m_address;
+ StartDebugger(command, 2, extra_argv);
Connect();
} // TransportManager::Launch()
@@ -263,6 +273,7 @@
jdwpTransportError err = m_env->Close();
CheckReturnStatus(err);
}
+ m_isConnected = false;
JDWP_TRACE_PROG("Reset: connection closed");
} // TransportManager::Reset()
@@ -317,8 +328,8 @@
throw TransportException(JDWP_ERROR_OUT_OF_MEMORY, JDWPTRANSPORT_ERROR_OUT_OF_MEMORY);
}
char* lastErrorMessage = GetLastTransportError();
- AgentBase::GetMemoryManager().Free(lastErrorMessage JDWP_FILE_LINE);
- throw TransportException(JDWP_ERROR_TRANSPORT_INIT, err);
+ // AgentBase::GetMemoryManager().Free(lastErrorMessage JDWP_FILE_LINE);
+ throw TransportException(JDWP_ERROR_TRANSPORT_INIT, err, lastErrorMessage);
} // TransportManager::CheckReturnStatus()
inline void
@@ -328,7 +339,7 @@
JDWP_TRACE_PACKET(message
<<" length=" << packet->type.cmd.len
<< " Id=" << packet->type.cmd.id
- << " flag=REPLY "
+ << " flag=REPLY"
<< " errorCode=" << (short)(packet->type.reply.errorCode));
} else {
JDWP_TRACE_PACKET(message
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.h?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.h (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/agent/core/TransportManager.h Mon Jul 23 09:18:27 2007
@@ -100,9 +100,9 @@
*
* @param command - a command line to start the debugger
*
- * @exception TransportException() - transport error happens.
+ * @exception AgentException() - any error happens.
*/
- void Launch(const char* command) throw(TransportException);
+ void Launch(const char* command) throw(AgentException);
/**
* The given function does a blocking read on an open connection.
@@ -153,14 +153,16 @@
jlong m_connectTimeout; // attachTimeout or acceptTimeout timeout
jlong m_handshakeTimeout; // handshakeTimeout
bool m_ConnectionPrepared; // if true PrepareConnection done
+ bool m_isConnected; // true if connection is established
bool m_isServer; // is jdwp agent server or not
+ const char* m_transportName; // transport name
char* m_address; // transport address
jdwpTransportEnv* m_env; // jdwpTransport environment
LoadedLibraryHandler m_loadedLib; // transport library handler
char* m_lastErrorMessage; // last error message
void CheckReturnStatus(jdwpTransportError err) throw(TransportException);
- void StartDebugger(const char* command) throw(AgentException);
+ void StartDebugger(const char* command, int extra_argc, const char* extra_argv[]) throw(AgentException);
void TracePacket(const char* message, const jdwpPacket* packet);
LoadedLibraryHandler LoadTransport(const char* dirName, const char* transportName);
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/transport/dt_socket/SocketTransport.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/transport/dt_socket/SocketTransport.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/transport/dt_socket/SocketTransport.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/common/transport/dt_socket/SocketTransport.cpp Mon Jul 23 09:18:27 2007
@@ -496,7 +496,7 @@
err = bind(serverSocket, (struct sockaddr *)&serverSockAddr, sizeof(serverSockAddr));
if (err == SOCKET_ERROR) {
- SetLastTranError(env, "connection failed", GetLastErrorStatus());
+ SetLastTranError(env, "binding to port failed", GetLastErrorStatus());
return JDWPTRANSPORT_ERROR_ILLEGAL_STATE ;
}
@@ -520,6 +520,9 @@
}
char* retAddress = 0;
+
+ // RI always returns only port number in listening mode
+/*
char portName[6];
sprintf(portName, "%d", ntohs(serverSockAddr.sin_port)); //instead of itoa()
@@ -530,7 +533,6 @@
if (strcmp(hostName, "0.0.0.0") == 0) {
gethostname(hostName, sizeof(hostName));
}
-
retAddress = (char*)(((internalEnv*)env->functions->reserved1)
->alloc)((jint)(strlen(hostName) + strlen(portName) + 2));
if (retAddress == 0) {
@@ -538,6 +540,14 @@
return JDWPTRANSPORT_ERROR_OUT_OF_MEMORY;
}
sprintf(retAddress, "%s:%s", hostName, portName);
+*/
+ retAddress = (char*)(((internalEnv*)env->functions->reserved1)->alloc)(6 + 1);
+ if (retAddress == 0) {
+ SetLastTranError(env, "out of memory", 0);
+ return JDWPTRANSPORT_ERROR_OUT_OF_MEMORY;
+ }
+ sprintf(retAddress, "%d", ntohs(serverSockAddr.sin_port));
+
*actualAddress = retAddress;
return JDWPTRANSPORT_ERROR_NONE;
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/core/TransportManager_pd.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/core/TransportManager_pd.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/core/TransportManager_pd.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/core/TransportManager_pd.cpp Mon Jul 23 09:18:27 2007
@@ -28,6 +28,8 @@
* constants, include statements and functions for Linux platform.
*/
+#include <unistd.h>
+#include <errno.h>
#include "TransportManager_pd.h"
#include "TransportManager.h"
@@ -37,27 +39,121 @@
const char* TransportManager::unLoadDecFuncName = "jdwpTransport_UnLoad";
const char TransportManager::pathSeparator = ':';
-void TransportManager::StartDebugger(const char* command) throw(AgentException)
+void TransportManager::StartDebugger(const char* command, int extra_argc, const char* extra_argv[]) throw(AgentException)
{
- throw NotImplementedException();
+ JDWP_TRACE_ENTRY("StartDebugger(" << JDWP_CHECK_NULL(command) << ',' << extra_argc << ',' << extra_argv << ')');
+
+ // allocate array for parsed arguments
+
+ int max_argc = 250 + extra_argc;
+ char** argv = static_cast<char**>(GetMemoryManager().Allocate((sizeof(char*) * (max_argc + 1)) JDWP_FILE_LINE));
+ AgentAutoFree afva(argv JDWP_FILE_LINE);
+
+ // parse command line
+ int argc = 0;
+ int cmd_len = strlen(command);
+ char* cmd = static_cast<char*>(GetMemoryManager().Allocate((cmd_len + 1) JDWP_FILE_LINE));
+ AgentAutoFree afv(cmd JDWP_FILE_LINE);
+
+ if (command != 0 && cmd_len > 0) {
+ JDWP_TRACE_PROG("StartDebugger: parse: cmd=" << JDWP_CHECK_NULL(command));
+
+ const char *arg = command, *p;
+ char *arg1 = cmd, *s;
+
+ for (; *arg != 0;) {
+
+ // skip initial spaces
+ while (isspace(*arg)) arg++;
+
+ // parse non-spaced or quoted argument
+ for (p = arg, s = arg1; ; p++) {
+ // check for quote
+ if (*p == '\"' || *p == '\'') {
+ char quote = *(p++);
+ // skip all chars until terminating quote or null
+ for (; *p != '\0'; p++) {
+ // check for terminating quote
+ if (*p == quote) {
+ p++;
+ break;
+ }
+ // preserve escaped quote
+ if (*p == '\\' && *(p + 1) == quote)
+ p++;
+ // store current char
+ *(s++) = *p;
+ }
+ }
+ // check for ending separator
+ if (*p == '\0' || isspace(*p)) {
+ *(s++) = '\0';
+ if (argc >= max_argc) {
+ JDWP_ERROR("Too many arguments for launching debugger proccess: " << argc);
+ throw AgentException(JDWP_ERROR_INTERNAL);
+ }
+ argv[argc++] = arg1;
+ JDWP_TRACE_PROG("StartDebugger: launch: arg[" << argc << "]=" << JDWP_CHECK_NULL(arg1));
+ arg = p;
+ arg1 = s;
+ break;
+ }
+ // skip escaped quote
+ if (*p == '\\' && (*(p + 1) == '\"' || *(p + 1) == '\''))
+ p++;
+ // store current char
+ *(s++) = *p;
+ }
+ }
+ }
+
+ // add extra arguments
+
+ int i;
+ for (i = 0; i < extra_argc; i++) {
+ if (extra_argv[i] != 0) {
+ JDWP_TRACE_PROG("StartDebugger: launch: arg[" << argc << "]=" << JDWP_CHECK_NULL(extra_argv[i]));
+ argv[argc++] = const_cast<char*>(extra_argv[i]);
+ }
+ }
+ argv[argc] = 0;
+
+ // launch debugger process
+
+ int pid = fork();
+ if (pid == -1) {
+ JDWP_ERROR("Failed to fork debugger process: error=" << errno);
+ throw AgentException(JDWP_ERROR_INTERNAL);
+ } else if (pid == 0) {
+ // execute debugger in child process
+ execv(argv[0], argv);
+ // returned here only in case of error, terminate child process
+ JDWP_DIE("Failed to execute debugger process: error=" << errno);
+ } else {
+ JDWP_TRACE_PROG("StartDebugger: launched: pid=" << pid);
+ }
}
ProcPtr jdwp::GetProcAddress(LoadedLibraryHandler libHandler, const char* procName)
{
+ JDWP_TRACE_ENTRY("GetProcAddress(" << libHandler << ',' << JDWP_CHECK_NULL(procName) << ')');
+
dlerror();
ProcPtr res = (ProcPtr)dlsym(libHandler, procName);
- char* errorMessage = 0;
- if (errorMessage = dlerror()) {
- JDWP_TRACE_PROG("free library failed (error: " << errorMessage << ")");
+ char* errorMessage = dlerror();
+ if (errorMessage) {
+ JDWP_TRACE_PROG("FreeLibrary: getting library entry failed (error: " << errorMessage << ")");
}
return res;
}
bool jdwp::FreeLibrary(LoadedLibraryHandler libHandler)
{
+ JDWP_TRACE_ENTRY("FreeLibrary(" << libHandler << ')');
+
dlerror();
if (dlclose(libHandler) != 0) {
- JDWP_TRACE_PROG("free library failed (error: " << dlerror() << ")");
+ JDWP_TRACE_PROG("FreeLibrary: closing library failed (error: " << dlerror() << ")");
return false;
}
return true;
@@ -65,6 +161,8 @@
LoadedLibraryHandler TransportManager::LoadTransport(const char* dirName, const char* transportName)
{
+ JDWP_TRACE_ENTRY("LoadTransport(" << JDWP_CHECK_NULL(dirName) << ',' << JDWP_CHECK_NULL(transportName) << ')');
+
JDWP_ASSERT(transportName != 0);
dlerror();
char* transportFullName = 0;
@@ -80,9 +178,9 @@
AgentAutoFree afv(transportFullName JDWP_FILE_LINE);
LoadedLibraryHandler res = dlopen(transportFullName, RTLD_LAZY);
if (res == 0) {
- JDWP_TRACE_PROG("loading of " << transportFullName << " failed (error: " << dlerror() << ")");
+ JDWP_TRACE_PROG("LoadTransport: loading library " << transportFullName << " failed (error: " << dlerror() << ")");
} else {
- JDWP_TRACE_PROG("transport " << transportFullName << " loaded");
+ JDWP_TRACE_PROG("LoadTransport: transport library " << transportFullName << " loaded");
}
return res;
}
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/makefile
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/makefile?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/makefile (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/agent/makefile Mon Jul 23 09:18:27 2007
@@ -28,7 +28,7 @@
INCLUDES += -I$(CMNAGENT)commands -I$(CMNAGENT)core \
-I$(COMMON)generic -Icore
-HYLDFLAGS += -lstdc++ -lgcc_s
+LDFLAGS += -lstdc++ -lgcc_s
BUILDFILES = \
$(CMNAGENT)commands/ArrayReference.o \
@@ -50,7 +50,7 @@
$(CMNAGENT)core/EventDispatcher.o $(CMNAGENT)core/LogManager.o $(CMNAGENT)core/MemoryManager.o \
$(CMNAGENT)core/ObjectManager.o $(CMNAGENT)core/OptionParser.o $(CMNAGENT)core/PacketDispatcher.o \
$(CMNAGENT)core/PacketParser.o $(CMNAGENT)core/RequestManager.o $(CMNAGENT)core/RequestModifier.o \
- $(CMNAGENT)core/ThreadManager.o $(CMNAGENT)core/TransportManager.o \
+ $(CMNAGENT)core/ThreadManager.o $(CMNAGENT)core/TransportManager.o $(CMNAGENT)core/AgentManager.o \
core/TransportManager_pd.o
MDLLIBFILES =
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/transport/makefile
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/transport/makefile?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/transport/makefile (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/unix/transport/makefile Mon Jul 23 09:18:27 2007
@@ -32,7 +32,7 @@
INCLUDES += -I$(CMNTRANS)common -I$(CMNTRANS)dt_socket \
-I$(COMMON)generic -Idt_socket
-HYLDFLAGS += -lstdc++ -lgcc_s
+LDFLAGS += -lstdc++ -lgcc_s
BUILDFILES = \
$(CMNTRANS)common/LastTransportError.o \
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/core/TransportManager_pd.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/core/TransportManager_pd.cpp?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/core/TransportManager_pd.cpp (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/core/TransportManager_pd.cpp Mon Jul 23 09:18:27 2007
@@ -45,13 +45,63 @@
const char TransportManager::pathSeparator = ';';
-void TransportManager::StartDebugger(const char* command) throw(AgentException)
+void TransportManager::StartDebugger(const char* command, int extra_argc, const char* extra_argv[]) throw(AgentException)
{
- throw NotImplementedException();
+ JDWP_TRACE_ENTRY("StartDebugger(" << JDWP_CHECK_NULL(command) << ',' << extra_argc << ',' << extra_argv << ')');
+
+JDWP_TRACE_PROG("StartDebugger: transport=" << JDWP_CHECK_NULL(extra_argv[0]));
+JDWP_TRACE_PROG("StartDebugger: address=" << JDWP_CHECK_NULL(extra_argv[1]));
+
+ // append extra arguments to command line
+
+ int cmd_len = strlen(command);
+ int extra_len = 0;
+ int i;
+
+ for (i = 0; i < extra_argc; i++) {
+ if (extra_argv[i] != 0) {
+ extra_len += strlen(extra_argv[i]) + 1;
+ }
+ }
+
+ char* cmd = static_cast<char*>(GetMemoryManager().Allocate((cmd_len + extra_len + 1) JDWP_FILE_LINE));
+ AgentAutoFree afv(cmd JDWP_FILE_LINE);
+ strcpy(cmd, command);
+
+ for (i = 0; i < extra_argc; i++) {
+ if (extra_argv[i] != 0) {
+ strcat(cmd, " ");
+ strcat(cmd, extra_argv[i]);
+ }
+ }
+
+ // launch debugger process
+
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZeroMemory(&pi, sizeof(pi));
+
+ JDWP_TRACE_PROG("StartDebugger: launch: cmd=" << JDWP_CHECK_NULL(cmd));
+
+ if(!CreateProcess(NULL, const_cast<LPSTR>(cmd), NULL, NULL,
+ TRUE, NULL, NULL, NULL, &si, &pi)) {
+ JDWP_ERROR("Failed to launch debugger process: error=" << GetLastError());
+ throw AgentException(JDWP_ERROR_INTERNAL);
+ }
+
+ JDWP_TRACE_PROG("StartDebugger: launched: pid=" << pi.dwProcessId);
+
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
}
LoadedLibraryHandler TransportManager::LoadTransport(const char* dirName, const char* transportName)
{
+ JDWP_TRACE_ENTRY("LoadTransport(" << JDWP_CHECK_NULL(dirName) << ',' << JDWP_CHECK_NULL(transportName) << ')');
+
JDWP_ASSERT(transportName != 0);
char* transportFullName = 0;
if (dirName == 0) {
@@ -66,9 +116,9 @@
AgentAutoFree afv(transportFullName JDWP_FILE_LINE);
LoadedLibraryHandler res = LoadLibrary(transportFullName);
if (res == 0) {
- JDWP_TRACE_PROG("loading of " << transportFullName << " failed (error code: " << GetLastError() << ")");
+ JDWP_TRACE_PROG("LoadTransport: loading library " << transportFullName << " failed (error code: " << GetLastError() << ")");
} else {
- JDWP_TRACE_PROG("transport " << transportFullName << " loaded");
+ JDWP_TRACE_PROG("LoadTransport: transport library " << transportFullName << " loaded");
}
return res;
}
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/makefile
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/makefile?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/makefile (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/main/native/jdwp/windows/agent/makefile Mon Jul 23 09:18:27 2007
@@ -54,7 +54,7 @@
$(CMNAGENT)core\EventDispatcher.obj $(CMNAGENT)core\LogManager.obj $(CMNAGENT)core\MemoryManager.obj \
$(CMNAGENT)core\ObjectManager.obj $(CMNAGENT)core\OptionParser.obj $(CMNAGENT)core\PacketDispatcher.obj \
$(CMNAGENT)core\PacketParser.obj $(CMNAGENT)core\RequestManager.obj $(CMNAGENT)core\RequestModifier.obj \
- $(CMNAGENT)core\ThreadManager.obj $(CMNAGENT)core\TransportManager.obj \
+ $(CMNAGENT)core\ThreadManager.obj $(CMNAGENT)core\TransportManager.obj $(CMNAGENT)core\AgentManager.obj \
core\TransportManager_pd.obj
VIRTFILES =
Modified: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/TestOptions.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/TestOptions.java?view=diff&rev=558788&r1=558787&r2=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/TestOptions.java (original)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/framework/TestOptions.java Mon Jul 23 09:18:27 2007
@@ -25,7 +25,6 @@
*/
package org.apache.harmony.jpda.tests.framework;
-import java.io.File;
import java.util.HashMap;
/**
@@ -52,6 +51,8 @@
* - full name of class to run debuggee with
* <li><code>jpda.settings.debuggeeVMExtraOptions</code>
* - extra options to run debuggee with
+ * <li><code>jpda.settings.debuggeeSuspend</code>
+ * - debuggee suspend mode ("y"|"n")
* <li><code>jpda.settings.transportWrapperClass</code>
* - class name of TransportWrapper implementation
* <li><code>jpda.settings.transportAddress</code>
@@ -83,6 +84,9 @@
public static final String DEFAULT_ATTACHING_ADDRESS = "127.0.0.1:9898";
/** Default port number for sync connection. */
+ public static final String DEFAULT_STATIC_SYNC_PORT = "9797";
+
+ /** Default port number for sync connection. */
public static final int DEFAULT_SYNC_PORT = 0;
/** Default class name for transport wrapper. */
@@ -211,7 +215,7 @@
return getProperty("jpda.settings.debuggeeAgentOptions",
"transport=dt_socket,address=" + address + ",server=" + serv
- + agentExtraOptions);
+ + ",suspend=" + getDebuggeeSuspend() + agentExtraOptions);
}
/**
@@ -269,6 +273,34 @@
String extOpts = getProperty("jpda.settings.debuggeeVMExtraOptions", "");
extOpts = extOpts + " -Djpda.settings.verbose=" + isVerbose();
return extOpts;
+ }
+
+ /**
+ * Returns debuggee suspend mode ("y"|"n").
+ *
+ * @return option "jpda.settings.debuggeeSuspend" or "y" by default
+ */
+ public String getDebuggeeSuspend() {
+ return getProperty("jpda.settings.debuggeeSuspend", "y");
+ }
+
+ /**
+ * Returns debuggee suspend mode ("y"|"n").
+ *
+ * @param mode
+ * suspend mode
+ */
+ public void setDebuggeeSuspend(String mode) {
+ setProperty("jpda.settings.debuggeeSuspend", mode);
+ }
+
+ /**
+ * Checks if debuggee is launched in suspend mode.
+ *
+ * @return true if debuggee is launched in suspend mode
+ */
+ public boolean isDebuggeeSuspend() {
+ return getDebuggeeSuspend().equals("y");
}
/**
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/LaunchedDebugger.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/LaunchedDebugger.java?view=auto&rev=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/LaunchedDebugger.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/LaunchedDebugger.java Mon Jul 23 09:18:27 2007
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand;
+
+import org.apache.harmony.jpda.tests.framework.LogWriter;
+import org.apache.harmony.jpda.tests.framework.TestErrorException;
+import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
+import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
+import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
+import org.apache.harmony.jpda.tests.framework.jdwp.Location;
+import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
+import org.apache.harmony.jpda.tests.jdwp.share.JDWPTestCase;
+import org.apache.harmony.jpda.tests.jdwp.share.JDWPUnitDebuggeeWrapper;
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+import org.apache.harmony.jpda.tests.share.JPDATestOptions;
+
+/**
+ * Base class for debuggers that are used in tests for DebuggerOnDemand functionality.
+ */
+public abstract class LaunchedDebugger extends JDWPTestCase {
+
+ // synchronization channel between debugger and debuggee
+ protected JPDADebuggeeSynchronizer synchronizer;
+
+ // synchronization channel between debugger and test
+ protected JPDADebuggeeSynchronizer testSynchronizer;
+
+ // name of tested debuggee class
+ public static final String DEBUGGEE_CLASS_NAME =
+ "org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthowDebuggerLaunchDebuggee";
+
+ // signature of the tested debuggee class
+ public static final String DEBUGGEE_CLASS_SIGNATURE = "L" + DEBUGGEE_CLASS_NAME + ";";
+
+ /**
+ * This method is invoked right before attaching to debuggee VM.
+ * It forces to use attaching connector and fixed transport address.
+ */
+/*
+ protected void beforeDebuggeeStart(JDWPOnDemandDebuggeeWrapper debugeeWrapper) {
+ settings.setAttachConnectorKind();
+ if (settings.getTransportAddress() == null) {
+ settings.setTransportAddress(JPDADebuggerOnDemandOptions.DEFAULT_ATTACHING_ADDRESS);
+ }
+ logWriter.println("DEBUGGER: Use ATTACH connector kind");
+
+ super.beforeDebuggeeStart(debuggeeWrapper);
+ }
+ */
+
+ /**
+ * Overrides inherited method to resume debuggee VM and then to establish
+ * sync connection with debuggee and server.
+ */
+ protected void internalSetUp() throws Exception {
+
+ // estabslish synch connection with test
+ logWriter.println("Establish synch connection between debugger and test");
+ JPDADebuggerOnDemandOptions debuggerSettings = new JPDADebuggerOnDemandOptions();
+ testSynchronizer = new JPDADebuggerOnDemandSynchronizer(logWriter, debuggerSettings);
+ testSynchronizer.startClient();
+ logWriter.println("Established synch connection between debugger and test");
+
+ // handle JDWP connection with debuggee
+ super.internalSetUp();
+
+ // establish synch connection with debuggee
+ logWriter.println("Establish synch connection between debugger and debuggee");
+ synchronizer = new JPDADebuggeeSynchronizer(logWriter, settings);;
+ synchronizer.startClient();
+ logWriter.println("Established synch connection between debugger and debuggee");
+ }
+
+ /**
+ * Creates wrapper for debuggee process.
+ */
+ protected JDWPUnitDebuggeeWrapper createDebuggeeWrapper() {
+ return new JPDADebuggerOnDemandDebuggeeWrapper(settings, logWriter);
+ }
+
+ /**
+ * Receives initial EXCEPTION event if debuggee is suspended on event.
+ */
+ protected void receiveInitialEvent() {
+ if (settings.isDebuggeeSuspend()) {
+ initialEvent =
+ debuggeeWrapper.vmMirror.receiveCertainEvent(JDWPConstants.EventKind.EXCEPTION);
+ logWriter.println("Received inital EXCEPTION event");
+ debuggeeWrapper.resume();
+ logWriter.println("Resumed debuggee VM");
+ }
+ }
+
+ /**
+ * Overrides inherited method to close sync connection upon exit.
+ */
+ protected void internalTearDown() {
+ // close synch connection with debuggee
+ if (synchronizer != null) {
+ synchronizer.stop();
+ logWriter.println("Closed synch connection between debugger and debuggee");
+ }
+
+ // close synch connection with test
+ if (testSynchronizer != null) {
+ testSynchronizer.stop();
+ logWriter.println("Closed synch connection between debugger and test");
+ }
+
+ // close connections with debuggee
+ super.internalTearDown();
+ }
+
+ protected String getDebuggeeClassName() {
+ return null;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+
+ /**
+ * This class contains information about frame of a java thread.
+ */
+ public class FrameInfo {
+ long frameID;
+ Location location;
+
+ public FrameInfo(long frameID, Location location) {
+ super();
+ this.frameID = frameID;
+ this.location = location;
+ }
+
+ /**
+ * @return Returns the frameID.
+ */
+ public long getFrameID() {
+ return frameID;
+ }
+ /**
+ * @return Returns the location.
+ */
+ public Location getLocation() {
+ return location;
+ }
+ }
+
+ protected FrameInfo[] jdwpGetFrames(long threadID, int startFrame, int length) {
+ CommandPacket packet = new CommandPacket(
+ JDWPCommands.ThreadReferenceCommandSet.CommandSetID,
+ JDWPCommands.ThreadReferenceCommandSet.FramesCommand);
+ packet.setNextValueAsThreadID(threadID);
+ packet.setNextValueAsInt(startFrame);
+ packet.setNextValueAsInt(length);
+
+ ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ if (!checkReplyPacketWithoutFail(reply, "ThreadReference::FramesCommand command")) {
+ throw new TestErrorException("Error during performing ThreadReference::Frames command");
+ }
+
+ int frames = reply.getNextValueAsInt();
+ FrameInfo[] frameInfos = new FrameInfo[frames];
+ for (int i = 0; i < frames; i++) {
+ long frameID = reply.getNextValueAsLong();
+ Location location = reply.getNextValueAsLocation();
+ frameInfos[i] = new FrameInfo(frameID, location);
+ }
+ return frameInfos;
+ }
+
+ protected long getClassIDBySignature(String signature) {
+ logWriter.println("=> Getting reference type ID for class: " + signature);
+ CommandPacket packet = new CommandPacket(
+ JDWPCommands.VirtualMachineCommandSet.CommandSetID,
+ JDWPCommands.VirtualMachineCommandSet.ClassesBySignatureCommand);
+ packet.setNextValueAsString(signature);
+ ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ if (!checkReplyPacketWithoutFail(reply, "VirtualMachine::ClassesBySignature command")) {
+ throw new TestErrorException("Error during performing VirtualMachine::ClassesBySignature command");
+ }
+ int classes = reply.getNextValueAsInt();
+ logWriter.println("=> Returned number of classes: " + classes);
+ long classID = 0;
+ for (int i = 0; i < classes; i++) {
+ reply.getNextValueAsByte();
+ classID = reply.getNextValueAsReferenceTypeID();
+ reply.getNextValueAsInt();
+ // we need the only class, even if there were multiply ones
+ break;
+ }
+ assertTrue("VirtualMachine::ClassesBySignature command returned invalid classID:<" +
+ classID + "> for signature " + signature, classID > 0);
+ return classID;
+ }
+
+ protected void printStackFrame(int NumberOfFrames, FrameInfo[] frameInfos) {
+ for (int i = 0; i < NumberOfFrames; i++) {
+ logWriter.println(" ");
+ logWriter
+ .println("=> #" + i + " frameID=" + frameInfos[i].frameID);
+ String methodName = "";
+ try {
+ methodName = getMethodName(frameInfos[i].location.classID,
+ frameInfos[i].location.methodID);
+ } catch (TestErrorException e) {
+ throw new TestErrorException(e);
+ }
+ logWriter.println("=> method name=" + methodName);
+ }
+ logWriter.println(" ");
+ }
+
+ protected String getMethodName(long classID, long methodID) {
+ CommandPacket packet = new CommandPacket(
+ JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
+ JDWPCommands.ReferenceTypeCommandSet.MethodsCommand);
+ packet.setNextValueAsClassID(classID);
+ ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
+ if (!checkReplyPacketWithoutFail(reply, "ReferenceType::Methods command")) {
+ throw new TestErrorException("Error during performing ReferenceType::Method command");
+ }
+ int methods = reply.getNextValueAsInt();
+ for (int i = 0; i < methods; i++) {
+ long mid = reply.getNextValueAsMethodID();
+ String name = reply.getNextValueAsString();
+ reply.getNextValueAsString();
+ reply.getNextValueAsInt();
+ if (mid == methodID) {
+ return name;
+ }
+ }
+ return "unknown";
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * This class provides functionality to establish synch connection between debugger and test.
+ */
+ protected static class JPDADebuggerOnDemandSynchronizer extends JPDADebuggeeSynchronizer {
+
+ public JPDADebuggerOnDemandSynchronizer(LogWriter logWriter, JPDADebuggerOnDemandOptions settings) {
+ super(logWriter, settings);
+ this.settings = settings;
+ }
+
+ public int getSyncPortNumber() {
+ return ((JPDADebuggerOnDemandOptions)settings).getSyncDebuggerPortNumber();
+ }
+ }
+
+ /**
+ * This class provides customization of DebuggeeWrapper that attaches to already launched debuggee.
+ */
+ protected static class JPDADebuggerOnDemandDebuggeeWrapper extends JDWPUnitDebuggeeWrapper {
+
+ public JPDADebuggerOnDemandDebuggeeWrapper(JPDATestOptions settings, LogWriter logWriter) {
+ super(settings, logWriter);
+ }
+
+ /**
+ * Attaches to already launched debuggee process and
+ * establishes JDWP connection.
+ */
+ public void start() {
+ try {
+ transport = createTransportWrapper();
+ openConnection();
+ logWriter.println("Established connection");
+ } catch (Exception e) {
+ throw new TestErrorException(e);
+ }
+ }
+
+ /**
+ * Closes all connections but does not wait for debuggee process to exit.
+ */
+ public void stop() {
+ disposeConnection();
+ closeConnection();
+ }
+ }
+
+ /**
+ * This class provides additional options to debuggers, that are used in DebuggerOnDemand tests.
+ * Currently the following additional options are supported:
+ * <ul>
+ * <li><i>jpda.settings.syncDebuggerPort</i>
+ * - port number for sync connection between debugger and test
+ * </ul>
+ *
+ */
+ protected static class JPDADebuggerOnDemandOptions extends JPDATestOptions {
+
+ public static final String DEFAULT_SYNC_DEBUGGER_PORT = "9899";
+
+ /**
+ * Returns port number string for sync connection between debugger and test.
+ */
+ public String getSyncDebuggerPortString() {
+ return getProperty("jpda.settings.syncDebuggerPort", null);
+ }
+
+ /**
+ * Returns port number for sync connection between debugger and test.
+ */
+ public int getSyncDebuggerPortNumber() {
+ String buf = getSyncDebuggerPortString();
+ if (buf == null) {
+ buf = DEFAULT_SYNC_DEBUGGER_PORT;
+ }
+
+ try {
+ return Integer.parseInt(buf);
+ } catch (NumberFormatException e) {
+ throw new TestErrorException(e);
+ }
+ }
+ }
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/LaunchedDebugger.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthowDebuggerLaunchDebuggee.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthowDebuggerLaunchDebuggee.java?view=auto&rev=558788
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthowDebuggerLaunchDebuggee.java (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthowDebuggerLaunchDebuggee.java Mon Jul 23 09:18:27 2007
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Aleksander V. Budniy
+ * @version $Revision: $
+ */
+
+/**
+ * Created on 5.06.2006
+ */
+package org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand;
+
+import org.apache.harmony.jpda.tests.share.Debuggee;
+import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer;
+
+/**
+ * This class provides simple debuggee class with deferred synch establishing.
+ *
+ * When debuggee throws exception, agent launches debugger, that connects to debuggee.
+ * Then debuggee establishes synch connection with debugger and invokes tested method.
+ */
+public class OnthowDebuggerLaunchDebuggee extends Debuggee {
+
+ public void onStart() {
+ super.onStart();
+
+ logWriter.println("DEBUGGEE: started");
+
+ // prepare for connection with debugger
+ logWriter.println("DEBUGGEE: bind for synch connection with debugger");
+ synchronizer = createSynchronizer();
+ synchronizer.bindServer();
+
+ // throw tested exception to launch debugger
+ try {
+ logWriter.println("DEBUGGEE: throw ExceptionForDebugger");
+ throw new ExceptionForDebugger();
+ } catch (ExceptionForDebugger e) {
+ logWriter.println("DEBUGGEE: cought ExceptionForDebugger: " + e);
+ }
+
+ // listen for connection with debugger
+ synchronizer.startServer();
+ logWriter.println("DEBUGGEE: established synch connection with debugger");
+ }
+
+ public void run() {
+ synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY);
+ synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE);
+ testMethod();
+ }
+
+ void testMethod() {
+ logWriter.println("DEBUGGEE: testMethod invoked");
+ }
+
+ protected JPDADebuggeeSynchronizer createSynchronizer() {
+ return new JPDADebuggeeSynchronizer(logWriter, settings);
+ }
+
+ public void onFinish() {
+ logWriter.println("DEBUGGEE: finished");
+
+ if (synchronizer != null) {
+ synchronizer.stop();
+ logWriter.println("DEBUGGEE: closed synch connection with debugger");
+ }
+ super.onFinish();
+ }
+
+ public static void main(String[] args) {
+ runDebuggee(OnthowDebuggerLaunchDebuggee.class);
+ }
+
+ protected JPDADebuggeeSynchronizer synchronizer;
+}
+
+class ExceptionForDebugger extends Exception {
+}
Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/test/common/unit/org/apache/harmony/jpda/tests/jdwp/DebuggerOnDemand/OnthowDebuggerLaunchDebuggee.java
------------------------------------------------------------------------------
svn:eol-style = native