You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by od...@apache.org on 2009/07/16 17:57:41 UTC
svn commit: r794726 [13/15] - in
/harmony/enhanced/jdktools/branches/java6/modules/jpda: ./
src/main/native/include/ src/main/native/jdwp/common/agent/commands/
src/main/native/jdwp/common/agent/core/
src/main/native/jdwp/common/generic/ src/main/nativ...
Modified: harmony/enhanced/jdktools/branches/java6/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/branches/java6/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp?rev=794726&r1=794725&r2=794726&view=diff
==============================================================================
--- harmony/enhanced/jdktools/branches/java6/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp (original)
+++ harmony/enhanced/jdktools/branches/java6/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.cpp Thu Jul 16 15:57:37 2009
@@ -15,25 +15,40 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/**
- * @author Vitaly A. Provodin, Pavel N. Vyssotski
- * @version $Revision: 1.32.2.1 $
- */
-#include <algorithm>
-
-#include "Log.h"
#include "ThreadManager.h"
+#include "Log.h"
#include "ClassManager.h"
#include "ObjectManager.h"
#include "EventDispatcher.h"
#include "RequestManager.h"
+#include "ExceptionManager.h"
using namespace jdwp;
namespace jdwp {
/**
+ * Contains information about Java threads only
+ */
+ class JavaThreadInfo : public AgentBase{
+ public:
+ jthread m_thread;
+ bool m_hasStepped;
+ JavaThreadInfo(JNIEnv *jni, jthread thrd)
+ {
+ m_thread = jni->NewGlobalRef(thrd);
+ if (m_thread == 0) {
+ JDWP_TRACE(LOG_RELEASE, (LOG_ERROR_FL, "Unable to allocate new global ref for JavaThreadInfo"));
+ }
+ m_hasStepped = false;
+ }
+ void Clean(JNIEnv *jni)
+ {
+ jni->DeleteGlobalRef(m_thread);
+ }
+ };
+
+ /**
* The structure containing thread information about
* internal agent threads and suspended java threads.
*/
@@ -67,6 +82,11 @@
bool m_isOnEvent;
/**
+ * Whether thread is alive
+ */
+ bool m_isAlive;
+
+ /**
* A constructor.
* Creates new instance.
* @param jni the JNI interface pointer.
@@ -75,14 +95,16 @@
* @param isOnEvent on event thread suspension.
*/
ThreadInfo(JNIEnv *jni, jthread thrd, bool isAgentThrd = false, bool isOnEvent = false)
- throw (OutOfMemoryException)
{
m_thread = jni->NewGlobalRef(thrd);
- if (m_thread == 0) throw OutOfMemoryException();
+ if (m_thread == 0) {
+ JDWP_TRACE(LOG_RELEASE, (LOG_ERROR_FL, "Unable to allocate new global ref for ThreadInfo"));
+ }
m_isAgentThread = isAgentThrd;
m_isOnEvent = isOnEvent;
m_suspendCount = 0;
m_threadName = 0;
+ m_isAlive = 1;
}
/**
@@ -108,10 +130,34 @@
void FindThreadInfo(JNIEnv *jni, ThreadInfoList *thrdInfoList, jthread thread,
ThreadInfoList::iterator &result)
{
- for (result = thrdInfoList->begin(); result != thrdInfoList->end(); result++) {
- if (*result != 0 &&
- jni->IsSameObject((*result)->m_thread, thread) == JNI_TRUE)
+ for (; result.hasNext();) {
+ ThreadInfo* element= result.getNext();
+ if (element != 0 &&
+ jni->IsSameObject((element)->m_thread, thread) == JNI_TRUE){
+ // TODO revert this JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "FindThreadInfo : agent thread=%p, name=%s, oldCount=%d, isOnEvent=%d", (element)->m_thread, JDWP_CHECK_NULL(((element)->m_thread)->m_threadName), ((element)->m_thread)->m_suspendCount, ((element)->m_thread)->m_isOnEvent));
break;
+ }
+ }
+ }
+
+ /**
+ * Looks for corresponding Java thread info in the Java thread
+ * info list
+ * @param jni - the JNI interface pointer
+ * @param javathrdInfoList - pointer to the Java thread info
+ * list
+ * @param thread - the Java thread
+ * @param result - iterator for the Java thread info list
+ */
+ void FindJavaThreadInfo(JNIEnv *jni, JavaThreadInfoList *javathrdInfoList, jthread thread,
+ JavaThreadInfoList::iterator &result)
+ {
+ for (; result.hasNext();) {
+ JavaThreadInfo* element= result.getNext();
+ if (element != 0 &&
+ jni->IsSameObject((element)->m_thread, thread) == JNI_TRUE){
+ break;
+ }
}
}
@@ -122,20 +168,23 @@
ThreadManager::~ThreadManager()
{
- JDWP_ASSERT(m_thrdmgrMonitor == 0);
- JDWP_ASSERT(m_execMonitor == 0);
+ /* FIXME - Temporary comment out for to avoid shutdown crash
+ JDWP_ASSERT(m_thrdmgrMonitor == 0);
+ JDWP_ASSERT(m_execMonitor == 0);*/
}
//-----------------------------------------------------------------------------
void
-ThreadManager::Init(JNIEnv *jni) throw()
+ThreadManager::Init(JNIEnv *jni)
{
- JDWP_TRACE_ENTRY("Init(" << jni << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "Init(%p)", jni));
+ JDWP_ASSERT(m_javathrdmgrMonitor == 0);
JDWP_ASSERT(m_thrdmgrMonitor == 0);
m_execMonitor = new AgentMonitor("_jdwp_ThreadManager_execMonitor");
+ m_javathrdmgrMonitor = new AgentMonitor("_jdwp_ThreadManager_javathrdmgrMonitor");
m_thrdmgrMonitor = new AgentMonitor("_jdwp_ThreadManager_thrdmgrMonitor");
m_stepMonitor = new AgentMonitor("_jdwp_ThreadManager_stepMonitor");
@@ -148,10 +197,11 @@
//-----------------------------------------------------------------------------
void
-ThreadManager::Clean(JNIEnv *jni) throw()
+ThreadManager::Clean(JNIEnv *jni)
{
- JDWP_TRACE_ENTRY("Clean(" << jni << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "Clean(%p)", jni));
+ /* Temporarily commented out to workaround shutdown crash
if(m_execMonitor !=0) {
delete m_execMonitor;
m_execMonitor = 0;
@@ -160,7 +210,7 @@
if(m_thrdmgrMonitor != 0) {
delete m_thrdmgrMonitor;
m_thrdmgrMonitor = 0;
- }
+ }*/
if (m_stepMonitor != 0) {
delete m_stepMonitor;
@@ -175,10 +225,10 @@
//-----------------------------------------------------------------------------
-void
-ThreadManager::Reset(JNIEnv *jni) throw(AgentException)
+int
+ThreadManager::Reset(JNIEnv *jni)
{
- JDWP_TRACE_ENTRY("Reset(" << jni << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "Reset(%p)", jni));
// delete not yet started but registered handlers for method invoke
if (m_execMonitor != 0) {
@@ -189,7 +239,8 @@
// resume all not internal threads and remove them from list
if (m_thrdmgrMonitor != 0) {
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
- ClearThreadList(jni);
+ int ret = ClearThreadList(jni);
+ JDWP_CHECK_RETURN(ret);
}
// reset flags and thread variable that are used in PopFrames process
@@ -198,39 +249,73 @@
m_popFramesMonitorReleased = false;
m_popFramesThread = 0;
}
+
+ return JDWP_ERROR_NONE;
}
//-----------------------------------------------------------------------------
-void
+int
ThreadManager::ClearThreadList(JNIEnv *jni)
{
- JDWP_TRACE_ENTRY("ClearThreadList(" << jni << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "ClearThreadList(%p)", jni));
- for (ThreadInfoList::iterator iter = m_threadInfoList.begin(); iter != m_threadInfoList.end(); iter++) {
- if (*iter == 0) continue;
- if (!(*iter)->m_isAgentThread) {
- JDWP_TRACE_THREAD("Reset: resume thread=" << (*iter)->m_thread
- << ", name=" << JDWP_CHECK_NULL((*iter)->m_threadName));
+ jthread packetDispatcher;
+ jthread eventDispatcher;
+
+ for (ThreadInfoList::iterator iter = m_threadInfoList.begin(); iter.hasNext();) {
+ ThreadInfo* element = iter.getNext();
+ if (element == NULL) continue;
+ if (!(element)->m_isAgentThread) {
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "Reset: resume thread=%p, name=%s", (element)->m_thread, JDWP_CHECK_NULL((element)->m_threadName)));
// resume thread
- GetObjectManager().DeleteFrameIDs(jni, (*iter)->m_thread);
+ GetObjectManager().DeleteFrameIDs(jni, (element)->m_thread);
jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->ResumeThread((*iter)->m_thread));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->ResumeThread((element)->m_thread));
// remove from list and destroy
- (*iter)->Clean(jni);
- delete *iter;
- *iter = 0;
+ iter.remove();
+ (element)->Clean(jni);
+ delete element;
+ element = NULL;
+ } else {
+ // get thread name
+ jvmtiError err;
+ jvmtiThreadInfo info;
+
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo((element)->m_thread, &info));
+ JvmtiAutoFree jafInfoName(info.name);
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
+ }
+ char* threadName = info.name;
+
+ // determine whether this agent thread should be retained
+ if( strcmp( threadName, "_jdwp_PacketDispatcher") == 0){
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "find packet dispatcher thread=%p, name=%s", (element)->m_thread, JDWP_CHECK_NULL((element)->m_threadName)));
+ packetDispatcher = (element)->m_thread;
+ }else if ( strcmp( threadName, "_jdwp_EventDispatcher") == 0){
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "find event dispatcher thread=%p, name=%s", (element)->m_thread, JDWP_CHECK_NULL((element)->m_threadName)));
+ eventDispatcher = (element)->m_thread;
+ }
}
}
m_threadInfoList.clear();
+
+ // Background agent threads should be added back to the list
+ AddThread(jni, packetDispatcher, true);
+ AddThread(jni, eventDispatcher, true);
+
+ return JDWP_ERROR_NONE;
}
//-----------------------------------------------------------------------------
void
-ThreadManager::ClearExecList(JNIEnv* jni) throw()
+ThreadManager::ClearExecList(JNIEnv* jni)
{
- JDWP_TRACE_ENTRY("ClearExecList(" << jni << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "ClearExecList(%p)", jni));
while (!m_execList.empty()) {
SpecialAsyncCommandHandler* handler = m_execList.back();
@@ -245,21 +330,21 @@
ThreadManager::RunAgentThread(JNIEnv *jni, jvmtiStartFunction proc,
const void *arg, jint priority,
const char *name, jthread thread)
- throw(AgentException)
+
{
- JDWP_TRACE_ENTRY("RunAgentThread(" << jni << ',' << proc
- << ',' << arg << ',' << priority
- << ',' << JDWP_CHECK_NULL(name) << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "RunAgentThread(%p,%p,%p,%d,%s,%p)", jni, proc, arg, priority, JDWP_CHECK_NULL(name), thread));
if (thread == 0) {
thread = CreateAgentThread(jni, name);
}
jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->RunAgentThread(thread, proc, arg, priority));
-
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->RunAgentThread(thread, proc, arg, priority));
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return 0;
+ }
return thread;
}
@@ -267,10 +352,9 @@
//-----------------------------------------------------------------------------
jthread
-ThreadManager::CreateAgentThread(JNIEnv *jni, const char *name) throw(AgentException)
+ThreadManager::CreateAgentThread(JNIEnv *jni, const char *name)
{
- JDWP_TRACE_ENTRY("CreateAgentThread(" << jni
- << ',' << JDWP_CHECK_NULL(name) << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "CreateAgentThread(%p,%s)", jni, JDWP_CHECK_NULL(name)));
jthread thrd;
ClassManager &clsMgr = GetClassManager();
@@ -305,28 +389,28 @@
ThreadInfo*
ThreadManager::AddThread(JNIEnv *jni, jthread thread, bool isAgentThread, bool isOnEvent)
- throw(AgentException)
+
{
- JDWP_TRACE_ENTRY("AddThread(" << jni << ',' << thread
- << ',' << isAgentThread << ',' << isOnEvent << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "AddThread(%p,%p,%s,%s)", jni, thread, (isAgentThread?"TRUE":"FALSE"), (isOnEvent?"TRUE":"FALSE")));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
- ThreadInfoList::iterator place = m_threadInfoList.end();
- ThreadInfoList::iterator result;
- for (result = m_threadInfoList.begin();
- result != m_threadInfoList.end(); result++) {
- if (*result == 0) {
+ jint place = -1,found = -1;
+ ThreadInfoList::iterator result = m_threadInfoList.begin();
+ for (;result.hasNext();) {
+ ThreadInfo* element = result.getNext();
+ if (element == NULL) {
// save pointer to empty slot
- place = result;
- } else if (jni->IsSameObject((*result)->m_thread, thread) == JNI_TRUE) {
+ place = result.getIndex();
+ } else if (jni->IsSameObject((element)->m_thread, thread) == JNI_TRUE) {
+ found = result.getIndex();
// thread found
break;
}
}
// not found
- if (result == m_threadInfoList.end())
+ if (found == -1)
{
ThreadInfo *thrdinf = new ThreadInfo(jni, thread, isAgentThread, isOnEvent);
@@ -336,71 +420,212 @@
jvmtiError err;
jvmtiThreadInfo info;
- JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(thread, &info));
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo(thread, &info));
+ if (err == JVMTI_ERROR_NONE) {
+ thrdinf->m_threadName = info.name;
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "AddThread: add thread=%p, name=%s", thread, JDWP_CHECK_NULL(thrdinf->m_threadName)));
+ }
+ }
+#endif // NDEBUG
- thrdinf->m_threadName = info.name;
+ if (place !=-1) {
+ m_threadInfoList.insert(place,thrdinf);
+ } else {
+ m_threadInfoList.push_back(thrdinf);
}
-#endif // NDEBUG
- JDWP_TRACE_THREAD("AddThread: add thread=" << thread
- << ", name=" << JDWP_CHECK_NULL(thrdinf->m_threadName));
+ return thrdinf;
+ }
+
+ return result.getCurrent();
+}
- if (place != m_threadInfoList.end()) {
- *place = thrdinf;
+//----------------------------------------------------------------------------
+
+void ThreadManager::RemoveThread(JNIEnv *jni, jthread thread) {
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "RemoveThread(%p,%p)", jni, thread));
+
+ MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
+
+ ThreadInfoList::iterator result = m_threadInfoList.begin();
+ for (;result.hasNext();) {
+ ThreadInfo* element = result.getNext();
+ if (element != NULL && jni->IsSameObject((element)->m_thread, thread) == JNI_TRUE) {
+ // thread found, remove from list and destroy
+ m_threadInfoList.remove(result.getIndex());
+ (element)->Clean(jni);
+ delete element;
+ element = 0;
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "RemoveThread: add thread=%p", thread));
+ break;
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+
+/**
+ * Add a Java thread to the internal Java thread info list
+ * @param jni - the JNI interface pointer
+ * @param thread - the Java thread to add
+ *
+ * @return JavaThreadInfo* - the Java thread info structure
+ * created for this thread
+ */
+JavaThreadInfo*
+ThreadManager::AddJavaThread(JNIEnv *jni, jthread thread)
+
+{
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "AddJavaThread(%p,%p)", jni, thread));
+
+ MonitorAutoLock lock(m_javathrdmgrMonitor JDWP_FILE_LINE);
+
+ jint place = -1,found = -1;
+ JavaThreadInfoList::iterator result = m_javaThreadInfoList.begin();
+ for (;result.hasNext();) {
+ JavaThreadInfo* element = result.getNext();
+ if (element == NULL) {
+ // save pointer to empty slot
+ place = result.getIndex();
+ } else if (jni->IsSameObject((element)->m_thread, thread) == JNI_TRUE) {
+ found = result.getIndex();
+ // thread found
+ break;
+ }
+ }
+
+ // not found
+ if (found == -1)
+ {
+ JavaThreadInfo *thrdinf = new JavaThreadInfo(jni, thread);
+
+#ifndef NDEBUG
+ // save thread name for debugging purpose
+ if (JDWP_TRACE_ENABLED(LOG_KIND_THREAD)) {
+ jvmtiError err;
+ jvmtiThreadInfo info;
+
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo(thread, &info));
+ JvmtiAutoFree jafInfoName(info.name);
+ if (err == JVMTI_ERROR_NONE) {
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "AddJavaThread: add thread=%p, name=%s", thread, JDWP_CHECK_NULL(info.name)));
+ }
+ }
+#endif // NDEBUG
+
+ if (place !=-1) {
+ m_javaThreadInfoList.insert(place,thrdinf);
} else {
- m_threadInfoList.push_back(thrdinf);
+ m_javaThreadInfoList.push_back(thrdinf);
}
return thrdinf;
}
- return *result;
+ return result.getCurrent();
}
+
+//----------------------------------------------------------------------------
+
+/**
+ * Remove a Java thread from the list
+ *
+ * @param jni - the JNI interface pointer
+ * @param thread - the Java thread to remove
+ */
+
+void ThreadManager::RemoveJavaThread(JNIEnv *jni, jthread thread) {
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "RemoveJavaThread(%p,%p)", jni, thread));
+
+ MonitorAutoLock lock(m_javathrdmgrMonitor JDWP_FILE_LINE);
+
+ JavaThreadInfoList::iterator result = m_javaThreadInfoList.begin();
+ for (;result.hasNext();) {
+ JavaThreadInfo* element = result.getNext();
+ if (element != NULL && jni->IsSameObject((element)->m_thread, thread) == JNI_TRUE) {
+ // thread found, remove from list and destroy
+ m_javaThreadInfoList.remove(result.getIndex());
+ (element)->Clean(jni);
+ delete element;
+ element = 0;
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "RemoveJavaThread: add thread=%p", thread));
+ break;
+ }
+ }
+}
+
+
//-----------------------------------------------------------------------------
-void
+int
ThreadManager::InternalSuspend(JNIEnv *jni, jthread thread, bool ignoreInternal, bool isOnEvent)
- throw(AgentException)
+
{
- JDWP_TRACE_ENTRY("InternalSuspend(" << jni << ',' << thread
- << ',' << ignoreInternal << ',' << isOnEvent << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "InternalSuspend(%p,%p,%s,%s)", jni, thread, (ignoreInternal?"TRUE":"FALSE"), (isOnEvent?"TRUE":"FALSE")));
// find thread
- ThreadInfoList::iterator place = m_threadInfoList.end();
- ThreadInfoList::iterator result;
- for (result = m_threadInfoList.begin();
- result != m_threadInfoList.end(); result++) {
- if (*result == 0) {
+ jint place = -1,found = -1;
+ ThreadInfoList::iterator result = m_threadInfoList.begin();
+ for (;result.hasNext(); ){
+ ThreadInfo* element = result.getNext();
+
+ if (element == NULL) {
// save pointer to empty slot
- place = result;
- } else if (jni->IsSameObject((*result)->m_thread, thread) == JNI_TRUE) {
+ place = result.getIndex();
+ } else if (jni->IsSameObject((element)->m_thread, thread) == JNI_TRUE) {
+ found = result.getIndex();
// thread found
break;
}
}
-
- if (result == m_threadInfoList.end())
+
+ if (found == -1)
{
// not in list -> suspend and add to list
jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->SuspendThread(thread));
+ jvmtiThreadInfo jvmtiInfo;
+
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo(thread, &jvmtiInfo));
+ JvmtiAutoFree jafInfoName(jvmtiInfo.name);
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
+ }
+
+ // ignore agent threads for AsyncCommandHandler
+ if (strncmp(jvmtiInfo.name, "_jdwp_", 6) == 0) {
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "InternalSuspend: ignore agent thread=%p, name=%s",
+ thread, jvmtiInfo.name));
+ return JDWP_ERROR_NONE;
+ }
+
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->SuspendThread(thread));
JDWP_ASSERT(err != JVMTI_ERROR_THREAD_SUSPENDED);
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
+ if (err != JVMTI_ERROR_NONE && err != JVMTI_ERROR_THREAD_NOT_ALIVE){
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "InternalSuspend: suspend error: %d", err));
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
+ }
// add thread
ThreadInfo *thrdinf = new ThreadInfo(jni, thread, false, isOnEvent);
thrdinf->m_suspendCount = 1 ;
- if (place != m_threadInfoList.end()) {
- *place = thrdinf;
+
+ if (err == JVMTI_ERROR_THREAD_NOT_ALIVE){
+ thrdinf->m_isAlive = 0 ;
+ }
+
+ if (place != -1) {
+ m_threadInfoList.insert(place,thrdinf);
} else {
- m_threadInfoList.push_back(thrdinf);
+ m_threadInfoList.push_back(thrdinf);
}
#ifndef NDEBUG
@@ -409,119 +634,126 @@
jvmtiError err;
jvmtiThreadInfo info;
- JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(thread, &info));
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
-
- thrdinf->m_threadName = info.name;
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo(thread, &info));
+// JvmtiAutoFree jafInfoName(info.name);
+ if (err == JVMTI_ERROR_NONE) {
+ thrdinf->m_threadName = info.name;
+ }
}
#endif // NDEBUG
- JDWP_TRACE_THREAD("InternalSuspend: suspend thread=" << thread
- << ", name=" << JDWP_CHECK_NULL(thrdinf->m_threadName)
- << ", oldCount=" << thrdinf->m_suspendCount
- << ", isOnEvent=" << thrdinf->m_isOnEvent);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "InternalSuspend: suspend thread=%p, name=%s, oldCount=%d, isOnEvent=%s",
+ thread, JDWP_CHECK_NULL(thrdinf->m_threadName), thrdinf->m_suspendCount, (thrdinf->m_isOnEvent?"TRUE":"FALSE")));
- } else if ((*result)->m_isAgentThread) {
+ } else if ((m_threadInfoList.getIndexof(found))->m_isAgentThread) {
// agent thread -> error (if not ignored)
- JDWP_TRACE_THREAD("InternalSuspend: ignore agent thread=" << thread
- << ", name=" << JDWP_CHECK_NULL((*result)->m_threadName)
- << ", oldCount=" << (*result)->m_suspendCount
- << ", isOnEvent=" << (*result)->m_isOnEvent);
+ ThreadInfo* element = m_threadInfoList.getIndexof(found);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "InternalSuspend: ignore agent thread=%p, name=%s, oldCount=%d, isOnEvent=%s",
+ thread, JDWP_CHECK_NULL((element)->m_threadName), (element)->m_suspendCount, ((element)->m_isOnEvent?"TRUE":"FALSE")));
if (!ignoreInternal) {
- throw AgentException(JVMTI_ERROR_INVALID_THREAD);
+ AgentException ex(JVMTI_ERROR_INVALID_THREAD);
+ JDWP_SET_EXCEPTION(ex);
+ return JVMTI_ERROR_INVALID_THREAD;
}
} else {
// already in list -> just increase suspend count
- JDWP_TRACE_THREAD("InternalSuspend: increase count thread=" << thread
- << ", name=" << JDWP_CHECK_NULL((*result)->m_threadName)
- << ", oldCount=" << (*result)->m_suspendCount
- << ", isOnEvent=" << (*result)->m_isOnEvent);
- JDWP_ASSERT((*result)->m_suspendCount > 0);
- (*result)->m_suspendCount++;
+ ThreadInfo* element = m_threadInfoList.getIndexof(found);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "InternalSuspend: increase count thread=%p, name=%s, oldCount=%d, isOnEvent=%s",
+ thread, JDWP_CHECK_NULL((element)->m_threadName), element->m_suspendCount, ((element)->m_isOnEvent?"TRUE":"FALSE")));
+ JDWP_ASSERT((element)->m_suspendCount > 0);
+ (element)->m_suspendCount++;
}
+
+ return JDWP_ERROR_NONE;
}
//-----------------------------------------------------------------------------
-void
-ThreadManager::Suspend(JNIEnv *jni, jthread thread, bool isOnEvent) throw(AgentException)
+int
+ThreadManager::Suspend(JNIEnv *jni, jthread thread, bool isOnEvent)
{
- JDWP_TRACE_ENTRY("Suspend(" << jni << ',' << thread << '.' << isOnEvent << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "Suspend(%p,%p,%s)", jni, thread, (isOnEvent?"TRUE":"FALSE")));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
- InternalSuspend(jni, thread, false, isOnEvent);
+ int ret = InternalSuspend(jni, thread, false, isOnEvent);
+ return ret;
}
//-----------------------------------------------------------------------------
-void
-ThreadManager::InternalResume(JNIEnv *jni, jthread thread, bool ignoreInternal) throw(AgentException)
+int
+ThreadManager::InternalResume(JNIEnv *jni, jthread thread, bool ignoreInternal)
{
- JDWP_TRACE_ENTRY("InternalResume(" << jni << ',' << thread << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "InternalResume(%p,%p)", jni, thread));
- ThreadInfoList::iterator result;
+ ThreadInfoList::iterator result= m_threadInfoList.begin();
FindThreadInfo(jni, &m_threadInfoList, thread, result);
-
- if (result == m_threadInfoList.end()) {
- // thread not yet suspended -> ignore
- } else if ((*result)->m_isAgentThread) {
+ if (!result.hasCurrent()) {
+ return JDWP_ERROR_NONE;
+ }
+ ThreadInfo* info = result.getCurrent();
+ if (info->m_isAgentThread) {
// agent thread -> error (if not ignored)
- JDWP_TRACE_THREAD("InternalResume: ignore agent thread=" << thread
- << ", name=" << JDWP_CHECK_NULL((*result)->m_threadName)
- << ", oldCount=" << (*result)->m_suspendCount
- << ", isOnEvent=" << (*result)->m_isOnEvent);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "InternalResume: ignore agent thread=%p, name=%s, oldCount=%d, isOnEvent=%s",
+ thread, JDWP_CHECK_NULL((info)->m_threadName), (info)->m_suspendCount, ((info)->m_isOnEvent?"TRUE":"FALSE")));
if (!ignoreInternal) {
- throw AgentException(JVMTI_ERROR_INVALID_THREAD);
+ AgentException ex(JVMTI_ERROR_INVALID_THREAD);
+ JDWP_SET_EXCEPTION(ex);
+ return JVMTI_ERROR_INVALID_THREAD;
}
- } else if ((*result)->m_suspendCount == 1) {
- // count == 1 -> resume thread
+ } else if (info->m_suspendCount == 1) {
+ // count == 1 -> resume thread if it is alive
GetObjectManager().DeleteFrameIDs(jni, thread);
+ if (info->m_isAlive == 1 ){
+ jvmtiError err;
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->ResumeThread(thread));
+ JDWP_ASSERT(err != JVMTI_ERROR_THREAD_NOT_SUSPENDED);
+
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
+ }
+ }
- jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->ResumeThread(thread));
-
- JDWP_ASSERT(err != JVMTI_ERROR_THREAD_NOT_SUSPENDED);
-
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
-
- JDWP_TRACE_THREAD("InternalResume: resume thread=" << thread
- << ", name=" << JDWP_CHECK_NULL((*result)->m_threadName)
- << ", oldCount=" << (*result)->m_suspendCount
- << ", isOnEvent=" << (*result)->m_isOnEvent);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "InternalResume: resume thread=%p, name=%s, oldCount=%d, isOnEvent=%s, isAlive=%s",
+ thread, JDWP_CHECK_NULL((info)->m_threadName), (info)->m_suspendCount, ((info)->m_isOnEvent?"TRUE":"FALSE"),
+ ((info)->m_isAlive?"TRUE":"FALSE")));
+
// remove from list and destroy
- (*result)->Clean(jni);
- delete *result;
- *result = 0;
+ m_threadInfoList.remove(result.getIndex());
+ (info)->Clean(jni);
+ delete info;
+ info = 0;
} else {
// count > 1 -> just decrease count
- JDWP_TRACE_THREAD("InternalResume: decrease count thread=" << thread
- << ", name=" << JDWP_CHECK_NULL((*result)->m_threadName)
- << ", oldCount=" << (*result)->m_suspendCount
- << ", isOnEvent=" << (*result)->m_isOnEvent);
- (*result)->m_suspendCount--;
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "InternalResume: decrease count thread=%p, name=%s, oldCount=%d, isOnEvent=%s",
+ thread, JDWP_CHECK_NULL((info)->m_threadName), (info)->m_suspendCount, ((info)->m_isOnEvent?"TRUE":"FALSE")));
+ (info)->m_suspendCount--;
}
+
+ return JDWP_ERROR_NONE;
}
//-----------------------------------------------------------------------------
-void
-ThreadManager::Resume(JNIEnv *jni, jthread thread) throw(AgentException)
+int
+ThreadManager::Resume(JNIEnv *jni, jthread thread)
{
- JDWP_TRACE_ENTRY("Resume(" << jni << ',' << thread << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "Resume(%p,%p)", jni, thread));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
- InternalResume(jni, thread, false);
+ int ret = InternalResume(jni, thread, false);
+ return ret;
}
//-----------------------------------------------------------------------------
-void
-ThreadManager::SuspendAll(JNIEnv *jni, jthread threadOnEvent) throw(AgentException)
+int
+ThreadManager::SuspendAll(JNIEnv *jni, jthread threadOnEvent)
{
- JDWP_TRACE_ENTRY("SuspendAll(" << jni << ',' << threadOnEvent << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "SuspendAll(%p,%p)", jni, threadOnEvent));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
@@ -529,23 +761,24 @@
jthread *threads = 0;
jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->GetAllThreads(&count, &threads));
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetAllThreads(&count, &threads));
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
+ }
+
JvmtiAutoFree dobj(threads);
for (jint i = 0; i < count; i++)
{
JDWP_ASSERT(threads[i] != 0);
- try
+ // suspend thread (ignoring internal)
+ bool isOnEvent = (threadOnEvent != 0 && jni->IsSameObject(threadOnEvent, threads[i]));
+ int ret = InternalSuspend(jni, threads[i], true, isOnEvent);
+ if (ret != JDWP_ERROR_NONE)
{
- // suspend thread (ignoring internal)
- bool isOnEvent = (threadOnEvent != 0 && jni->IsSameObject(threadOnEvent, threads[i]));
- InternalSuspend(jni, threads[i], true, isOnEvent);
- }
- catch (const AgentException &e)
- {
- jvmtiError errTemp = (jvmtiError)e.ErrCode();
+ jvmtiError errTemp = (jvmtiError)ret;
JDWP_ASSERT(errTemp != JVMTI_ERROR_THREAD_NOT_SUSPENDED);
@@ -553,108 +786,119 @@
errTemp != JVMTI_ERROR_THREAD_NOT_ALIVE &&
errTemp != JVMTI_ERROR_INVALID_THREAD)
{
- err = errTemp;
+ return errTemp;
}
}
}
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
+ return JDWP_ERROR_NONE;
}
//-----------------------------------------------------------------------------
-void
-ThreadManager::ResumeAll(JNIEnv *jni) throw(AgentException)
+int
+ThreadManager::ResumeAll(JNIEnv *jni)
{
- JDWP_TRACE_ENTRY("ResumeAll(" << jni << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "ResumeAll(%p)", jni));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
// resume all not internal threads and remove from list
- for (ThreadInfoList::iterator iter = m_threadInfoList.begin(); iter != m_threadInfoList.end(); iter++) {
-
- if (*iter == 0) continue;
+ for (ThreadInfoList::iterator iter = m_threadInfoList.begin(); iter.hasNext();) {
+
+ ThreadInfo* element = iter.getNext();
+
+ if (element == NULL) continue;
- if (!(*iter)->m_isAgentThread) {
+ if (!(element)->m_isAgentThread) {
// check suspend count
- JDWP_ASSERT((*iter)->m_suspendCount > 0);
- if ((*iter)->m_suspendCount == 1) {
-
+ JDWP_ASSERT((element)->m_suspendCount > 0);
+ if ((element)->m_suspendCount == 1) {
// resume application thread
- JDWP_TRACE_THREAD("ResumeAll: resume thread=" << (*iter)->m_thread
- << ", name=" << JDWP_CHECK_NULL((*iter)->m_threadName)
- << ", oldCount=" << (*iter)->m_suspendCount
- << ", isOnEvent=" << (*iter)->m_isOnEvent);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "ResumeAll: resume thread=%p, name=%s, oldCount=%d, isOnEvent=%s, isAlive=%s",
+ (element)->m_thread, JDWP_CHECK_NULL((element)->m_threadName), (element)->m_suspendCount,
+ ((element)->m_isOnEvent?"TRUE":"FALSE"), ((element)->m_isAlive?"TRUE":"FALSE")));
+
// destroy stack frame IDs
- GetObjectManager().DeleteFrameIDs(jni, (*iter)->m_thread);
+ GetObjectManager().DeleteFrameIDs(jni, (element)->m_thread);
// resume thread
- jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->ResumeThread((*iter)->m_thread));
-
- JDWP_ASSERT(err != JVMTI_ERROR_THREAD_NOT_SUSPENDED);
- JDWP_ASSERT(err != JVMTI_ERROR_INVALID_TYPESTATE);
- JDWP_ASSERT(err != JVMTI_ERROR_INVALID_THREAD);
- JDWP_ASSERT(err != JVMTI_ERROR_THREAD_NOT_ALIVE);
-
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
-
+ // resume thread if it is still alive
+ if ((element)->m_isAlive == 1 ){
+ jvmtiError err;
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->ResumeThread((element)->m_thread));
+
+ JDWP_ASSERT(err != JVMTI_ERROR_THREAD_NOT_SUSPENDED);
+ JDWP_ASSERT(err != JVMTI_ERROR_INVALID_TYPESTATE);
+ JDWP_ASSERT(err != JVMTI_ERROR_INVALID_THREAD);
+ JDWP_ASSERT(err != JVMTI_ERROR_THREAD_NOT_ALIVE);
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
+ }
+ }
// remove from list and destroy
- (*iter)->Clean(jni);
- delete *iter;
- *iter = 0;
+ (element)->Clean(jni);
+ // set the slot to null
+ m_threadInfoList.insertNULL(iter.getIndex());
+ delete element;
} else {
// just decrease suspend count
- JDWP_TRACE_THREAD("ResumeAll: decrease count thread=" << (*iter)->m_thread
- << ", name=" << JDWP_CHECK_NULL((*iter)->m_threadName)
- << ", oldCount=" << (*iter)->m_suspendCount
- << ", isOnEvent=" << (*iter)->m_isOnEvent);
- (*iter)->m_suspendCount--;
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "ResumeAll: decrease count thread=%p, name=%s, oldCount=%d, isOnEvent=%s",
+ (element)->m_thread, JDWP_CHECK_NULL((element)->m_threadName), (element)->m_suspendCount,
+ ((element)->m_isOnEvent?"TRUE":"FALSE")));
+ (element)->m_suspendCount--;
}
} else {
// ignore agent thread
- JDWP_TRACE_THREAD("ResumeAll: ignore agent thread=" << (*iter)->m_thread
- << ", name=" << JDWP_CHECK_NULL((*iter)->m_threadName)
- << ", oldCount=" << (*iter)->m_suspendCount
- << ", isOnEvent=" << (*iter)->m_isOnEvent);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "ResumeAll: ignore agent thread=%p, name=%s, oldCount=%d, isOnEvent=%s",
+ (element)->m_thread, JDWP_CHECK_NULL((element)->m_threadName), (element)->m_suspendCount,
+ ((element)->m_isOnEvent?"TRUE":"FALSE")));
}
}
+
+ return JDWP_ERROR_NONE;
}
//-----------------------------------------------------------------------------
-void
-ThreadManager::Interrupt(JNIEnv *jni, jthread thread) throw(AgentException)
+int
+ThreadManager::Interrupt(JNIEnv *jni, jthread thread)
{
- JDWP_TRACE_ENTRY("Interrupt(" << jni << ',' << thread << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "Interrupt(%p,%p)", jni, thread));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->InterruptThread(thread));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->InterruptThread(thread));
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ }
+ return err;
}
//-----------------------------------------------------------------------------
-void
+int
ThreadManager::Stop(JNIEnv *jni, jthread thread, jobject throwable)
- throw(AgentException)
+
{
- JDWP_TRACE_ENTRY("Stop(" << jni << ',' << thread << ',' << throwable << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "Stop(%p,%p,%p)", jni, thread, throwable));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->StopThread(thread, throwable));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->StopThread(thread, throwable));
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ }
+ return err;
}
//-----------------------------------------------------------------------------
@@ -662,7 +906,7 @@
void
ThreadManager::Join(JNIEnv *jni, jthread thread)
{
- JDWP_TRACE_ENTRY("Join(" << jni << ',' << thread << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "Join(%p,%p)", jni, thread));
ClassManager &clsMgr = GetClassManager();
jclass threadClass = clsMgr.GetThreadClass();
@@ -680,39 +924,95 @@
bool
ThreadManager::IsAgentThread(JNIEnv *jni, jthread thread)
{
- //JDWP_TRACE_ENTRY("IsAgentThread(" << jni << ',' << thread << ')');
+ //JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "IsAgentThread(%p,%d)", jni, thread));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
bool ret_value = false;
- ThreadInfoList::iterator result;
+ ThreadInfoList::iterator result = m_threadInfoList.begin();
FindThreadInfo(jni, &m_threadInfoList, thread, result);
-
+
// found
- if (result != m_threadInfoList.end())
- ret_value = (*result)->m_isAgentThread;
+ if (result.hasCurrent())
+ ret_value = (result.getCurrent())->m_isAgentThread;
return ret_value;
}
//-----------------------------------------------------------------------------
+/**
+ * Set a boolean for the specified thread indicating if the last
+ * action was a single step
+ *
+ * @param jni - the JNI interface pointer
+ * @param thread - the Java thread
+ * @param hasStepped - indicates if the last action was a single
+ * step
+ */
+void
+ThreadManager::SetHasStepped(JNIEnv *jni, jthread thread, bool hasStepped) {
+ MonitorAutoLock lock(m_javathrdmgrMonitor JDWP_FILE_LINE);
+ JavaThreadInfoList::iterator result = m_javaThreadInfoList.begin();
+ FindJavaThreadInfo(jni, &m_javaThreadInfoList, thread, result);
+
+ jvmtiThreadInfo info;
+ jvmtiError err;
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo(thread, &info));
+ JvmtiAutoFree jafInfoName(info.name);
+
+ // If we have found a matching entry, set it's value
+ if (result.hasCurrent()) {
+ (result.getCurrent())->m_hasStepped = hasStepped;
+ }
+}
+
+/**
+ * Return an indication of whether the last action on the
+ * specified Java thread was a single step.
+ *
+ * @param jni - the JNI interface pointer
+ * @param thread - the Java thread to query
+ *
+ * @return bool - indicates if the last action was a single step
+ */
+bool
+ThreadManager::HasStepped(JNIEnv *jni, jthread thread) {
+ MonitorAutoLock lock(m_javathrdmgrMonitor JDWP_FILE_LINE);
+ JavaThreadInfoList::iterator result = m_javaThreadInfoList.begin();
+ FindJavaThreadInfo(jni, &m_javaThreadInfoList, thread, result);
+
+ jvmtiThreadInfo info;
+ jvmtiError err;
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo(thread, &info));
+ JvmtiAutoFree jafInfoName(info.name);
+
+ // If we have found a matching entry, return it's value
+ if (result.hasCurrent()) {
+ return (result.getCurrent())->m_hasStepped;
+ }
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+
jint
ThreadManager::GetSuspendCount(JNIEnv *jni, jthread thread)
{
- //JDWP_TRACE_ENTRY("GetSuspendCount(" << jni << ',' << thread << ')');
+ //JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "GetSuspendCount(%p,%d)", jni, thread));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
jint ret_value = 0;
- ThreadInfoList::iterator result;
+ ThreadInfoList::iterator result = m_threadInfoList.begin();
FindThreadInfo(jni, &m_threadInfoList, thread, result);
// found
- if (result != m_threadInfoList.end())
- ret_value = (*result)->m_suspendCount;
+ if (result.hasCurrent())
+ ret_value = (result.getCurrent())->m_suspendCount;
return ret_value;
}
@@ -720,20 +1020,20 @@
//-----------------------------------------------------------------------------
bool
-ThreadManager::IsSuspendedOnEvent(JNIEnv *jni, jthread thrd) throw (AgentException)
+ThreadManager::IsSuspendedOnEvent(JNIEnv *jni, jthread thrd)
{
- //JDWP_TRACE_ENTRY("IsSuspendedOnEvent(" << thrd << ')');
+ //JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "IsSuspendedOnEvent(" << thrd << ')'));
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
bool ret_value = false;
- ThreadInfoList::iterator result;
+ ThreadInfoList::iterator result = m_threadInfoList.begin();
FindThreadInfo(jni, &m_threadInfoList, thrd, result);
// found
- if (result != m_threadInfoList.end())
- ret_value = (*result)->m_isOnEvent;
+ if (result.hasCurrent())
+ ret_value = (result.getCurrent())->m_isOnEvent;
return ret_value;
}
@@ -741,72 +1041,133 @@
//-----------------------------------------------------------------------------
bool
-ThreadManager::IsSuspended(jthread thrd) throw (AgentException)
+ThreadManager::IsSuspended(jthread thrd)
{
- //JDWP_TRACE_ENTRY("IsSuspended(" << thrd << ')');
-
- MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
+ //JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "IsSuspended(" << thrd << ')'));
jint thread_state;
jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadState(thrd, &thread_state));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadState(thrd, &thread_state));
JDWP_ASSERT(err != JVMTI_ERROR_NULL_POINTER);
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
+ if (err != JVMTI_ERROR_NONE) {
+ JDWP_TRACE(LOG_RELEASE, (LOG_ERROR_FL, "Error calling GetThreadState: %d", err));
+ return false;
+ }
return (thread_state & JVMTI_THREAD_STATE_SUSPENDED) != 0;
}
//-----------------------------------------------------------------------------
-void
+int
+ThreadManager::CheckThreadStatus(JNIEnv *jni, jthread thrd)
+{
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "CheckThreadStatus(%p)", thrd));
+ // check the thread status
+ MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
+
+ // check whether the reference is a thread reference
+ jclass threadClass = GetClassManager().GetThreadClass();
+ if( !jni->IsInstanceOf(thrd, threadClass) )
+ {
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "## CheckThreadStatus: thread reference is not a valid thread reference "));
+ AgentException ex(JVMTI_ERROR_INVALID_THREAD);
+ JDWP_SET_EXCEPTION(ex);
+ return JVMTI_ERROR_INVALID_THREAD;
+ }
+
+ // check in the suspend thread list
+ bool isSuspened = false;
+ ThreadInfoList::iterator result = m_threadInfoList.begin();
+ FindThreadInfo(jni, &m_threadInfoList, thrd, result);
+ // not found
+ if (!result.hasCurrent())
+ {
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "## CheckThreadStatus: thread is not in suspended thread list: %p", thrd));
+ AgentException ex(JVMTI_ERROR_THREAD_NOT_SUSPENDED);
+ JDWP_SET_EXCEPTION(ex);
+ return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
+ }
+
+ jint thread_state;
+ jvmtiError err;
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadState(thrd, &thread_state));
+
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
+ }
+
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "CheckThreadStatus: check thread status: %d", thread_state));
+ if( thread_state & JVMTI_THREAD_STATE_TERMINATED) {
+ AgentException ex(JVMTI_ERROR_INVALID_THREAD);
+ JDWP_SET_EXCEPTION(ex);
+ return JVMTI_ERROR_INVALID_THREAD;
+ }
+
+ if( !(thread_state & JVMTI_THREAD_STATE_SUSPENDED) ) {
+ AgentException ex(JVMTI_ERROR_THREAD_NOT_SUSPENDED);
+ JDWP_SET_EXCEPTION(ex);
+ return JVMTI_ERROR_THREAD_NOT_SUSPENDED;
+ }
+
+ return JDWP_ERROR_NONE;
+}
+
+//-----------------------------------------------------------------------------
+
+int
ThreadManager::RegisterInvokeHandler(JNIEnv *jni, SpecialAsyncCommandHandler* handler)
- throw (AgentException)
+
{
- JDWP_TRACE_ENTRY("RegisterInvokeHandler(" << jni << ',' << handler << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "RegisterInvokeHandler(%p,%p)", jni, handler));
JDWP_ASSERT(handler->GetThread() != 0);
// check if thread is suspended on event
MonitorAutoLock lock(m_thrdmgrMonitor JDWP_FILE_LINE);
- ThreadInfoList::iterator result;
+ ThreadInfoList::iterator result = m_threadInfoList.begin();
FindThreadInfo(jni, &m_threadInfoList, handler->GetThread(), result);
- if (result == m_threadInfoList.end() || !(*result)->m_isOnEvent)
- throw AgentException(JDWP_ERROR_THREAD_NOT_SUSPENDED);
+ if (!result.hasCurrent() || !(result.getCurrent())->m_isOnEvent) {
+ AgentException ex(JDWP_ERROR_THREAD_NOT_SUSPENDED);
+ JDWP_SET_EXCEPTION(ex);
+ return JDWP_ERROR_THREAD_NOT_SUSPENDED;
+ }
- JDWP_TRACE_THREAD("RegisterInvokeHandler: handler=" << handler
- << ", thread=" << (*result)->m_thread
- << ", name=" << JDWP_CHECK_NULL((*result)->m_threadName)
- << ", options=" << handler->GetOptions());
+ ThreadInfo* info = result.getCurrent();
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "RegisterInvokeHandler: handler=%p, thread=%p, name=%s, options=%d",
+ handler, (info)->m_thread, JDWP_CHECK_NULL((info)->m_threadName), handler->GetOptions()));
{
MonitorAutoLock lock(m_execMonitor JDWP_FILE_LINE);
m_execList.push_back(handler);
}
+ int ret;
if ((handler->GetOptions() & JDWP_INVOKE_SINGLE_THREADED) == 0) {
- JDWP_TRACE_THREAD("RegisterInvokeHandler -- resume all before method invoke: thread="
- << handler->GetThread());
- ResumeAll(jni);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "RegisterInvokeHandler -- resume all before method invoke: thread=%p", handler->GetThread()));
+ ret = ResumeAll(jni);
} else {
- JDWP_TRACE_THREAD("RegisterInvokeHandler -- resume before method invoke: thread="
- << handler->GetThread());
- Resume(jni, handler->GetThread());
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "RegisterInvokeHandler -- resume before method invoke: thread=%p", handler->GetThread()));
+ ret = Resume(jni, handler->GetThread());
}
+
+ return ret;
}
SpecialAsyncCommandHandler*
ThreadManager::FindInvokeHandler(JNIEnv* jni, jthread thread)
- throw (AgentException)
+
{
- JDWP_TRACE_ENTRY("FindInvokeHandler(" << jni << ',' << thread << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "FindInvokeHandler(%p,%p)", jni, thread));
MonitorAutoLock lock(m_execMonitor JDWP_FILE_LINE);
- for (ExecListIterator i = m_execList.begin(); i != m_execList.end(); i++) {
- SpecialAsyncCommandHandler* handler = *i;
+ for (ExecListIterator i = m_execList.begin(); i.hasNext();) {
+ SpecialAsyncCommandHandler* handler = i.getNext();
if (jni->IsSameObject(thread, handler->GetThread())) {
m_execList.erase(i);
return handler;
@@ -826,25 +1187,24 @@
void ThreadManager::HandleInternalSingleStep(JNIEnv* jni, jthread thread,
jmethodID method, jlocation location)
- throw(AgentException)
+
{
- JDWP_TRACE_ENTRY("HandleInternalSingleStep(" << jni << ',' << thread << ','
- << method << ',' << location << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "HandleInternalSingleStep(%p,%p,&p,%lld)", jni, thread, method, location));
- char* threadName = 0;
+ //char* threadName = 0;
char* methodName = 0;
#ifndef NDEBUG
if (JDWP_TRACE_ENABLED(LOG_KIND_THREAD)) {
jvmtiError err;
- JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodName(method, &methodName, 0, 0));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetMethodName(method, &methodName, 0, 0));
// don't invoke GetThreadInfo() because it may issue extra STEP events
// jvmtiThreadInfo threadInfo;
- // JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(thread, &threadInfo));
+ // JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo(thread, &threadInfo));
// threadName = threadInfo.name;
}
#endif // NDEBUG
- JvmtiAutoFree threadNameAutoFree(threadName);
+ //JvmtiAutoFree threadNameAutoFree(threadName);
JvmtiAutoFree methodNameAutoFree(methodName);
{
@@ -855,38 +1215,35 @@
m_popFramesMonitorReleased = true;
m_popFramesMonitor->NotifyAll();
- JDWP_TRACE_THREAD("HandleInternalSingleStep: thread on suspention point:"
- // << " thread=" << JDWP_CHECK_NULL(threadName)
- << " thread=" << thread
- << ",method=" << JDWP_CHECK_NULL(methodName)
- << ",location=" << location);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "HandleInternalSingleStep: thread on suspention point: thread=%p, method=%s, location=%lld",
+ thread, JDWP_CHECK_NULL(methodName), location));
}
// wait for suspend on suspention point
m_stepMonitorReleased = false;
while (!m_stepMonitorReleased) {
m_stepMonitor->Wait();
}
- JDWP_TRACE_THREAD("HandleInternalSingleStep: thread resumed:"
- // << " thread=" << JDWP_CHECK_NULL(threadName)
- << " thread=" << thread
- << ",method=" << JDWP_CHECK_NULL(methodName)
- << ",location=" << location);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "HandleInternalSingleStep: thread resumed: thread=%p, method=%s, location=%lld",
+ thread, JDWP_CHECK_NULL(methodName), location));
}
// execute registered MethodInvoke hadlers if needed
GetEventDispatcher().ExecuteInvokeMethodHandlers(jni, thread);
}
-void ThreadManager::PerformPopFrames(JNIEnv* jni, jint framesToPop, jthread thread)
- throw(AgentException)
+int ThreadManager::PerformPopFrames(JNIEnv* jni, jint framesToPop, jthread thread)
+
{
- JDWP_TRACE_ENTRY("PerformPopFrames(" << jni << ',' << framesToPop << ',' << thread << ')');
+ JDWP_TRACE_ENTRY(LOG_RELEASE, (LOG_FUNC_FL, "PerformPopFrames(%p,%d,%p)", jni, framesToPop, thread));
MonitorAutoLock thrdmgrMonitorLock(m_thrdmgrMonitor JDWP_FILE_LINE);
-
+ int ret;
+
// thread should be suspended
if (!GetThreadManager().IsSuspended(thread)) {
- throw AgentException(JDWP_ERROR_THREAD_NOT_SUSPENDED);
+ AgentException ex(JDWP_ERROR_THREAD_NOT_SUSPENDED);
+ JDWP_SET_EXCEPTION(ex);
+ return JDWP_ERROR_THREAD_NOT_SUSPENDED;
}
// The following check is disabled, because JVMTI and JDWP specifications
@@ -903,11 +1260,10 @@
#ifndef NDEBUG
if (JDWP_TRACE_ENABLED(LOG_KIND_THREAD)) {
jvmtiThreadInfo threadInfo;
- JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(thread, &threadInfo));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetThreadInfo(thread, &threadInfo));
threadName = threadInfo.name;
}
#endif // NDEBUG
- JvmtiAutoFree af(threadName);
// The following check is just for sure.
// This algorithm supposes that there are no invoke method handlers registered.
@@ -915,93 +1271,105 @@
{
MonitorAutoLock lockExecList(m_execMonitor JDWP_FILE_LINE);
if (!m_execList.empty()) {
- throw AgentException(JDWP_ERROR_THREAD_NOT_SUSPENDED);
+ AgentException ex(JDWP_ERROR_THREAD_NOT_SUSPENDED);
+ JDWP_SET_EXCEPTION(ex);
+ return JDWP_ERROR_THREAD_NOT_SUSPENDED;
}
}
jint frameCount;
- JVMTI_TRACE(err, GetJvmtiEnv()->GetFrameCount(thread, &frameCount));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetFrameCount(thread, &frameCount));
if (err != JVMTI_ERROR_NONE) {
- throw AgentException(err);
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
}
if (frameCount <= framesToPop) {
- throw AgentException(JDWP_ERROR_INVALID_FRAMEID);
+ AgentException ex(JDWP_ERROR_INVALID_FRAMEID);
+ JDWP_SET_EXCEPTION(ex);
+ return JDWP_ERROR_INVALID_FRAMEID;
}
// if there is native frame, pop frame can't be performed
- CheckNativeFrameExistence(thread, framesToPop);
+ ret = CheckNativeFrameExistence(thread, framesToPop);
+ JDWP_CHECK_RETURN(ret);
MonitorAutoLock popFramesMonitorLock(m_popFramesMonitor JDWP_FILE_LINE);
- try {
- m_popFramesThread = thread;
+ m_popFramesThread = thread;
- // enabling step request on thread where PopFrame command is performed
- JDWP_TRACE_THREAD("PerformPopFrames: enable internal step: thread="
- << JDWP_CHECK_NULL(threadName));
- GetRequestManager().EnableInternalStepRequest(jni, m_popFramesThread);
-
- // cycle where topmost frames are popped one after one
- for (int i = 0; i < framesToPop; i++) {
- // pop topmost frame, thread is already suspended on event
- JDWP_TRACE_THREAD("PerformPopFrames: pop: frame#=" << i
- << ", thread=" << JDWP_CHECK_NULL(threadName));
- JVMTI_TRACE(err, GetJvmtiEnv()->PopFrame(m_popFramesThread));
- if (err != JVMTI_ERROR_NONE) {
- throw AgentException(err);
- }
+ // enabling step request on thread where PopFrame command is performed
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: enable internal step: thread=%s", JDWP_CHECK_NULL(threadName)));
+ ret = GetRequestManager().EnableInternalStepRequest(jni, m_popFramesThread);
+ JDWP_CHECK_RETURN(ret);
+
+ // cycle where topmost frames are popped one after one
+ for (int i = 0; i < framesToPop; i++) {
+ // pop topmost frame, thread is already suspended on event
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: pop: frame#=%d, thread=%s", i, JDWP_CHECK_NULL(threadName)));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->PopFrame(m_popFramesThread));
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: disable internal step: thread=%s", JDWP_CHECK_NULL(threadName)));
+ GetRequestManager().DisableInternalStepRequest(jni, m_popFramesThread);
+ m_popFramesThread = 0;
+ return err;
+ }
- // resume thread
- JDWP_TRACE_THREAD("PerformPopFrames: resume: thread="
- << JDWP_CHECK_NULL(threadName));
- JVMTI_TRACE(err, GetJvmtiEnv()->ResumeThread(m_popFramesThread));
- JDWP_ASSERT(err != JVMTI_ERROR_THREAD_NOT_SUSPENDED);
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
-
- // wait for thread to achieve suspention point in InternalSingleStep handler
- JDWP_TRACE_THREAD("PerformPopFrames: wait for step: thread="
- << JDWP_CHECK_NULL(threadName));
- m_popFramesMonitorReleased = false;
- while (!m_popFramesMonitorReleased) {
- m_popFramesMonitor->Wait();
- }
-
- {
- // suspend thread on suspention point
- MonitorAutoLock stepMonitorLock(m_stepMonitor JDWP_FILE_LINE);
- JDWP_TRACE_THREAD("PerformPopFrames: suspend: thread="
- << JDWP_CHECK_NULL(threadName));
- JVMTI_TRACE(err, GetJvmtiEnv()->SuspendThread(m_popFramesThread));
- JDWP_ASSERT(err != JVMTI_ERROR_THREAD_SUSPENDED);
- if (err != JVMTI_ERROR_NONE)
- throw AgentException(err);
-
- // notify suspended thread on suspention point
- m_stepMonitorReleased = true;
- m_stepMonitor->NotifyAll();
- JDWP_TRACE_THREAD("PerformPopFrames: notify: thread="
- << JDWP_CHECK_NULL(threadName));
- }
+ // resume thread
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: resume: thread=%s", JDWP_CHECK_NULL(threadName)));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->ResumeThread(m_popFramesThread));
+ JDWP_ASSERT(err != JVMTI_ERROR_THREAD_NOT_SUSPENDED);
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: disable internal step: thread=%s", JDWP_CHECK_NULL(threadName)));
+ GetRequestManager().DisableInternalStepRequest(jni, m_popFramesThread);
+ m_popFramesThread = 0;
+ return err;
}
- GetObjectManager().DeleteFrameIDs(jni, m_popFramesThread);
-
- JDWP_TRACE_THREAD("PerformPopFrames: disable internal step: thread="
- << JDWP_CHECK_NULL(threadName));
- GetRequestManager().DisableInternalStepRequest(jni, m_popFramesThread);
- m_popFramesThread = 0;
- } catch (AgentException& e) {
- JDWP_INFO("JDWP error: " << e.what() << " [" << e.ErrCode() << "]");
- JDWP_TRACE_THREAD("PerformPopFrames: disable internal step: thread="
- << JDWP_CHECK_NULL(threadName));
- GetRequestManager().DisableInternalStepRequest(jni, m_popFramesThread);
- m_popFramesThread = 0;
- throw(e);
+ // wait for thread to achieve suspention point in InternalSingleStep handler
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: wait for step: thread=%s", JDWP_CHECK_NULL(threadName)));
+ m_popFramesMonitorReleased = false;
+ while (!m_popFramesMonitorReleased) {
+ m_popFramesMonitor->Wait();
+ }
+
+ {
+ // suspend thread on suspention point
+ MonitorAutoLock stepMonitorLock(m_stepMonitor JDWP_FILE_LINE);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: suspend: thread=%s", JDWP_CHECK_NULL(threadName)));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->SuspendThread(m_popFramesThread));
+ JDWP_ASSERT(err != JVMTI_ERROR_THREAD_SUSPENDED);
+ if (err != JVMTI_ERROR_NONE) {
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: disable internal step: thread=%s", JDWP_CHECK_NULL(threadName)));
+ GetRequestManager().DisableInternalStepRequest(jni, m_popFramesThread);
+ m_popFramesThread = 0;
+ return err;
+ }
+
+ // notify suspended thread on suspention point
+ m_stepMonitorReleased = true;
+ m_stepMonitor->NotifyAll();
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: notify: thread=%s", JDWP_CHECK_NULL(threadName)));
+ }
+
}
+ GetObjectManager().DeleteFrameIDs(jni, m_popFramesThread);
+
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "PerformPopFrames: disable internal step: thread=%s", JDWP_CHECK_NULL(threadName)));
+ ret = GetRequestManager().DisableInternalStepRequest(jni, m_popFramesThread);
+ m_popFramesThread = 0;
+ JDWP_CHECK_RETURN(ret);
+
+ return JDWP_ERROR_NONE;
}
-void ThreadManager::CheckNativeFrameExistence(jthread thread, jint framesToPop)
- throw(AgentException)
+int ThreadManager::CheckNativeFrameExistence(jthread thread, jint framesToPop)
+
{
jvmtiFrameInfo* frames = static_cast<jvmtiFrameInfo*>
(GetMemoryManager().Allocate((framesToPop+1)
@@ -1012,12 +1380,14 @@
jvmtiError err;
// check (framesToPop+1) frames, because both the called
// and calling methods must be non-native
- JVMTI_TRACE(err, GetJvmtiEnv()->GetStackTrace(thread, 0,
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetStackTrace(thread, 0,
(framesToPop+1), frames, &count));
if (err != JVMTI_ERROR_NONE) {
- throw AgentException(err);
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
}
- JDWP_TRACE_THREAD("CheckNativeFrameExistence: FramesToCheck=" << count);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "CheckNativeFrameExistence: FramesToCheck=%d", count));
jboolean isNative = false;
for (int i = 0; i < count; i++) {
@@ -1030,28 +1400,29 @@
#ifndef NDEBUG
if (JDWP_TRACE_ENABLED(LOG_KIND_THREAD)) {
jclass clazz = 0;
- JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodName(methodID, &methodName, 0, 0));
- JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodDeclaringClass(methodID, &clazz));
- JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(clazz, &classSignature, 0));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetMethodName(methodID, &methodName, 0, 0));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetMethodDeclaringClass(methodID, &clazz));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->GetClassSignature(clazz, &classSignature, 0));
- JDWP_TRACE_THREAD("CheckNativeFrameExistence: method="
- << JDWP_CHECK_NULL(methodName)
- << ", class=" << JDWP_CHECK_NULL(classSignature));
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "CheckNativeFrameExistence: method=%s, class=%s", JDWP_CHECK_NULL(methodName), JDWP_CHECK_NULL(classSignature)));
}
#endif // NDEBUG
JvmtiAutoFree methodNameAutoFree(methodName);
JvmtiAutoFree classSignatureAutoFree(classSignature);
- JVMTI_TRACE(err, GetJvmtiEnv()->IsMethodNative(methodID, &isNative));
+ JVMTI_TRACE(LOG_DEBUG, err, GetJvmtiEnv()->IsMethodNative(methodID, &isNative));
if (err != JVMTI_ERROR_NONE) {
- throw AgentException(err);
+ AgentException ex(err);
+ JDWP_SET_EXCEPTION(ex);
+ return err;
}
if (isNative) {
- JDWP_TRACE_THREAD("CheckNativeFrameExistence: method="
- << JDWP_CHECK_NULL(methodName)
- << ", class=" << JDWP_CHECK_NULL(classSignature)
- << " is native");
- throw AgentException(JDWP_ERROR_NATIVE_METHOD);
+ JDWP_TRACE(LOG_RELEASE, (LOG_THREAD_FL, "CheckNativeFrameExistence: method=%s, class=%s is native", JDWP_CHECK_NULL(methodName), JDWP_CHECK_NULL(classSignature)));
+ AgentException ex(JDWP_ERROR_NATIVE_METHOD);
+ JDWP_SET_EXCEPTION(ex);
+ return JDWP_ERROR_NATIVE_METHOD;
}
}
+
+ return JDWP_ERROR_NONE;
}
Modified: harmony/enhanced/jdktools/branches/java6/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/branches/java6/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h?rev=794726&r1=794725&r2=794726&view=diff
==============================================================================
--- harmony/enhanced/jdktools/branches/java6/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h (original)
+++ harmony/enhanced/jdktools/branches/java6/modules/jpda/src/main/native/jdwp/common/agent/core/ThreadManager.h Thu Jul 16 15:57:37 2009
@@ -15,12 +15,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/**
- * @author Vitaly A. Provodin, Pavel N. Vyssotski
- * @version $Revision: 1.16.2.1 $
- */
-
/**
* @file
* ThreadManager.h
@@ -30,24 +24,26 @@
#ifndef _THREAD_MANAGER_H_
#define _THREAD_MANAGER_H_
-#include <vector>
+#include "Util.h"
#include "jni.h"
#include "jvmti.h"
#include "AgentBase.h"
#include "AgentException.h"
#include "AgentMonitor.h"
-#include "AgentAllocator.h"
#include "CommandHandler.h"
namespace jdwp {
+ class JavaThreadInfo;
+
class ThreadInfo;
- typedef vector<ThreadInfo*, AgentAllocator<ThreadInfo*> > ThreadInfoList;
+ typedef JDWPVector<ThreadInfo> ThreadInfoList;
- typedef vector<SpecialAsyncCommandHandler*,
- AgentAllocator<SpecialAsyncCommandHandler*> > ExecList;
+ typedef JDWPVector<JavaThreadInfo> JavaThreadInfoList;
+
+ typedef JDWPVector<SpecialAsyncCommandHandler> ExecList;
typedef ExecList::iterator ExecListIterator;
@@ -63,7 +59,8 @@
/**
* Constructs a new <code>ThreadManager</code> object.
*/
- ThreadManager() throw() :
+ ThreadManager() :
+ m_javathrdmgrMonitor(0),
m_thrdmgrMonitor(0),
m_execMonitor(0),
m_stepMonitor(0),
@@ -78,14 +75,14 @@
*
* @param jni - the JNI interface pointer
*/
- void Init(JNIEnv *jni) throw();
+ void Init(JNIEnv *jni);
/**
* Cleans the <code>ThreadManager</code> object.
*
* @param jni - the JNI interface pointer
*/
- void Clean(JNIEnv *jni) throw();
+ void Clean(JNIEnv *jni);
/**
* Reinitializes <code>ThreadManager</code> object.
@@ -97,7 +94,7 @@
* @exception AgentException is thrown in case of a
* universal error, with the corresponded error code.
*/
- void Reset(JNIEnv *jni) throw(AgentException);
+ int Reset(JNIEnv *jni);
/**
* Creates a new agent thread and starts the specified function in it.
@@ -126,7 +123,7 @@
jthread RunAgentThread(JNIEnv *jni, jvmtiStartFunction proc,
const void *arg, jint priority,
const char *name = 0,
- jthread thread = 0) throw(AgentException);
+ jthread thread = 0);
/**
* Adds an information about the thread parameter into
@@ -145,7 +142,60 @@
* is available for allocation.
*/
ThreadInfo* AddThread(JNIEnv *jni, jthread thread,
- bool isAgentThread = false, bool isOnEvent = false) throw(AgentException);
+ bool isAgentThread = false, bool isOnEvent = false);
+
+ /**
+ * remove the thread from internal list. If the thread is not in the
+ * list, nothing to do.
+ *
+ * @param jni - the JNI interface pointer
+ * @param thread - the thread to be removed
+ *
+ */
+ void RemoveThread(JNIEnv *jni, jthread thread);
+
+ /**
+ * Add the specified Java thread to the internal list. If the
+ * thread is already in the list, does nothing.
+ *
+ * @param jni - the JNI interface pointer
+ * @param thread - the Java thread to be added
+ *
+ * @return Pointer to the new record in the thread list
+ */
+ JavaThreadInfo* AddJavaThread(JNIEnv *jni, jthread thread);
+
+ /**
+ * Remove the specified Java thread to the internal list. If the
+ * thread is not in the list, does nothing.
+ *
+ * @param jni - the JNI interface pointer
+ * @param thread - the Java thread to be removed
+ */
+ void RemoveJavaThread(JNIEnv *jni, jthread thread);
+
+ /**
+ * Record in the Java thread list whether the last action on
+ * this thread was a single step.
+ * @param jni - the JNI interface pointer
+ * @param thread - the Java thread
+ * @param hasStepped - indicates if the last action was a
+ * single step
+ */
+ void SetHasStepped(JNIEnv *jni, jthread thread, bool hasStepped);
+
+ /**
+ * Returns an indicator of whether the last action on the
+ * specified thread was a single step.
+ *
+ * @param jni - the JNI interface pointer
+ * @param thread - the Java thread to query
+ *
+ * @return bool - indicates if the last action was a
+ * single step
+ */
+ bool HasStepped(JNIEnv *jni, jthread thread);
+
/**
* Suspends the specified thread.
* If the specified thread is an agent thread, calling this method
@@ -163,7 +213,7 @@
* @exception AgentException(JVMTI_ERROR_THREAD_NOT_ALIVE)
* is thrown if thread has not been started or is dead.
*/
- void Suspend(JNIEnv *jni, jthread thread, bool isOnEvent = false) throw(AgentException);
+ int Suspend(JNIEnv *jni, jthread thread, bool isOnEvent = false);
/**
* Resumes the specified thread.
@@ -181,7 +231,7 @@
* @exception AgentException(JVMTI_ERROR_THREAD_NOT_ALIVE)
* is thrown if thread has not been started or is dead.
*/
- void Resume(JNIEnv *jni, jthread thread) throw(AgentException);
+ int Resume(JNIEnv *jni, jthread thread);
/**
* Suspends all non-agent threads.
@@ -192,7 +242,7 @@
* @exception AgentException is thrown in case an universal
* error, with the corresponded error code.
*/
- void SuspendAll(JNIEnv *jni, jthread threadOnEvent = 0) throw(AgentException);
+ int SuspendAll(JNIEnv *jni, jthread threadOnEvent = 0);
/**
* Resumes all non-agent threads.
@@ -202,7 +252,7 @@
* @exception AgentException is thrown in case an universal
* error, with the corresponded error code.
*/
- void ResumeAll(JNIEnv *jni) throw(AgentException);
+ int ResumeAll(JNIEnv *jni);
/**
* Interrupts the specified thread.
@@ -215,7 +265,7 @@
* @exception AgentException(JVMTI_ERROR_THREAD_NOT_ALIVE)
* is thrown if thread has not been started or is dead.
*/
- void Interrupt(JNIEnv *jni, jthread thread) throw(AgentException);
+ int Interrupt(JNIEnv *jni, jthread thread);
/**
* Stops the specified thread.
@@ -231,8 +281,7 @@
* @exception AgentException(JVMTI_ERROR_INVALID_OBJECT)
* is thrown if exception is not an object.
*/
- void Stop(JNIEnv *jni, jthread thread, jobject throwable)
- throw(AgentException);
+ int Stop(JNIEnv *jni, jthread thread, jobject throwable);
/**
* Join the specified thread.
@@ -278,7 +327,7 @@
* @exception AgentException(JVMTI_ERROR_INVALID_THREAD)
* is thrown if the thread is not a thread object.
*/
- bool IsSuspendedOnEvent(JNIEnv *jni, jthread thrd) throw (AgentException);
+ bool IsSuspendedOnEvent(JNIEnv *jni, jthread thrd);
/**
* Checks if the specified thread is really suspended.
@@ -291,7 +340,21 @@
* @exception AgentException(JVMTI_ERROR_INVALID_THREAD)
* is thrown if the thread is not a thread object.
*/
- bool IsSuspended(jthread thrd) throw (AgentException);
+ bool IsSuspended(jthread thrd);
+
+ /**
+ * Check the status of specified thread, if it is in invalid status,
+ * throw corresponging exception in case.
+ *
+ * @param jni - the JNI interface pointer
+ * @param thread - the thread to be checked
+ *
+ * @exception AgentException(JVMTI_ERROR_INVALID_THREAD)
+ * is thrown if the thread is not a valid thread.
+ * AgentException(JVMTI_ERROR_THREAD_NOT_SUSPENDED)
+ * is thrown if the thread is not suspended.
+ */
+ int CheckThreadStatus(JNIEnv *jni,jthread thrd);
/**
* Registers instance of <code>SpecialAsyncCommandHandler</code> for
@@ -307,8 +370,7 @@
* is thrown if the specified thread has not been suspended by
* an event.
*/
- void RegisterInvokeHandler(JNIEnv *jni, SpecialAsyncCommandHandler* handler)
- throw (AgentException);
+ int RegisterInvokeHandler(JNIEnv *jni, SpecialAsyncCommandHandler* handler);
/**
* Finds an instance of <code>SpecialAsyncCommandHandler</code> from
@@ -323,7 +385,7 @@
* @exception AgentException is thrown if any error occurs.
*/
SpecialAsyncCommandHandler* FindInvokeHandler(JNIEnv *jni,
- jthread thread) throw (AgentException);
+ jthread thread);
/**
* Used for internal purposes. Handles <code>Step Event</code>,
@@ -336,7 +398,7 @@
*
* @exception AgentException is thrown if any error occurs.
*/
- void HandleInternalSingleStep(JNIEnv* jni, jthread thread, jmethodID method, jlocation location) throw(AgentException);
+ void HandleInternalSingleStep(JNIEnv* jni, jthread thread, jmethodID method, jlocation location);
/**
* Pops <code>framesToPop</code> number of frames on the specified thread.
@@ -347,8 +409,7 @@
*
* @exception AgentException is thrown if any error occurs.
*/
- void PerformPopFrames(JNIEnv* jni, jint framesToPop, jthread thread)
- throw(AgentException);
+ int PerformPopFrames(JNIEnv* jni, jint framesToPop, jthread thread);
/**
* Checks if <code>PopFrames</code> command is executed on the specified
@@ -362,6 +423,16 @@
private:
/**
+ * Track details of Java threads
+ */
+ JavaThreadInfoList m_javaThreadInfoList;
+
+ /**
+ * Monitor for <code>m_javaThreadInfoList</code>.
+ */
+ AgentMonitor *m_javathrdmgrMonitor;
+
+ /**
* List of suspended threads and agent threads.
*/
ThreadInfoList m_threadInfoList;
@@ -402,8 +473,7 @@
* @exception AgentException(JDWP_ERROR_NATIVE_METHOD)
* is thrown if native frame is found.
*/
- void CheckNativeFrameExistence(jthread thread, jint numberOfFrames)
- throw(AgentException);
+ int CheckNativeFrameExistence(jthread thread, jint numberOfFrames);
/**
* Creates a new agent thread and adds it to the list.
@@ -420,20 +490,19 @@
* @exception InternalErrorException is thrown in any other
* cases.
*/
- jthread CreateAgentThread(JNIEnv *jni, const char *name = 0)
- throw(AgentException);
+ jthread CreateAgentThread(JNIEnv *jni, const char *name = 0);
// synchronized
- void ClearExecList(JNIEnv* jni) throw();
+ void ClearExecList(JNIEnv* jni);
// synchronized
- void ClearThreadList(JNIEnv *jni);
+ int ClearThreadList(JNIEnv *jni);
// not synchronized
- void InternalResume(JNIEnv *jni, jthread thread, bool ignoreInternal) throw(AgentException);
+ int InternalResume(JNIEnv *jni, jthread thread, bool ignoreInternal);
// not synchronized
- void InternalSuspend(JNIEnv *jni, jthread thread, bool ignoreInternal, bool isOnEvent = false) throw(AgentException);
+ int InternalSuspend(JNIEnv *jni, jthread thread, bool ignoreInternal, bool isOnEvent = false);
};//class ThreadManager