1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send events to the debugger. 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/JdwpPriv.h" 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/JdwpConstants.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/JdwpHandler.h" 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/JdwpEvent.h" 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "jdwp/ExpandBuf.h" 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stddef.h> /* for offsetof() */ 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectGeneral notes: 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThe event add/remove stuff usually happens from the debugger thread, 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectin response to requests from the debugger, but can also happen as the 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectresult of an event in an arbitrary thread (e.g. an event with a "count" 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectmod expires). It's important to keep the event list locked when processing 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectevents. 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectEvent posting can happen from any thread. The JDWP thread will not usually 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpost anything but VM start/death, but if a JDWP request causes a class 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectto be loaded, the ClassPrepare event will come from the JDWP thread. 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectWe can have serialization issues when we post an event to the debugger. 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectFor example, a thread could send an "I hit a breakpoint and am suspending 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectmyself" message to the debugger. Before it manages to suspend itself, the 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectdebugger's response ("not interested, resume thread") arrives and is 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectprocessed. We try to resume a thread that hasn't yet suspended. 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThis means that, after posting an event to the debugger, we need to wait 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfor the event thread to suspend itself (and, potentially, all other threads) 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbefore processing any additional requests from the debugger. While doing 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectso we need to be aware that multiple threads may be hitting breakpoints 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projector other events simultaneously, so we either need to wait for all of them 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projector serialize the events with each other. 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectThe current mechanism works like this: 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Event thread: 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - If I'm going to suspend, grab the "I am posting an event" token. Wait 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for it if it's not currently available. 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - Post the event to the debugger. 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - If appropriate, suspend others and then myself. As part of suspending 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project myself, release the "I am posting" token. 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JDWP thread: 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - When an event arrives, see if somebody is posting an event. If so, 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sleep until we can acquire the "I am posting an event" token. Release 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project it immediately and continue processing -- the event we have already 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project received should not interfere with other events that haven't yet 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project been posted. 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSome care must be taken to avoid deadlock: 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - thread A and thread B exit near-simultaneously, and post thread-death 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project events with a "suspend all" clause 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - thread A gets the event token, thread B sits and waits for it 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project - thread A wants to suspend all other threads, but thread B is waiting 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for the token and can't be suspended 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSo we need to mark thread B in such a way that thread A doesn't wait for it. 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectIf we just bracket the "grab event token" call with a change to VMWAIT 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbefore sleeping, the switch back to RUNNING state when we get the token 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectwill cause thread B to suspend (remember, thread A's global suspend is 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstill in force, even after it releases the token). Suspending while 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectholding the event token is very bad, because it prevents the JDWP thread 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfrom processing incoming messages. 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectWe need to change to VMWAIT state at the *start* of posting an event, 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectand stay there until we either finish posting the event or decide to 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectput ourselves to sleep. That way we don't interfere with anyone else and 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectdon't allow anyone else to interfere with us. 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/ 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kJdwpEventCommandSet 64 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kJdwpCompositeCommand 100 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Stuff to compare against when deciding if a mod matches. Only the 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * values for mods valid for the event being evaluated will be filled in. 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The rest will be zeroed. 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 103d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostruct ModBasket { 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const JdwpLocation* pLoc; /* LocationOnly */ 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* className; /* ClassMatch/ClassExclude */ 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId threadId; /* ThreadOnly */ 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId classId; /* ClassOnly */ 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project RefTypeId excepClassId; /* ExceptionOnly */ 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool caught; /* ExceptionOnly */ 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FieldId field; /* FieldOnly */ 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId thisPtr; /* InstanceOnly */ 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* nothing for StepOnly -- handled differently */ 113d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro}; 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the next "request" serial number. We use this when sending 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * packets to the debugger. 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmJdwpNextRequestSerial(JdwpState* state) 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgLockMutex(&state->serialLock); 1222d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro u4 result = state->requestSerial++; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgUnlockMutex(&state->serialLock); 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get the next "event" serial number. We use this in the response to 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * message type EventRequest.Set. 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectu4 dvmJdwpNextEventSerial(JdwpState* state) 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgLockMutex(&state->serialLock); 1352d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro u4 result = state->eventSerial++; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgUnlockMutex(&state->serialLock); 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Lock the "event" mutex, which guards the list of registered events. 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void lockEventMutex(JdwpState* state) 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dvmDbgThreadWaiting(); 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgLockMutex(&state->eventLock); 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //dvmDbgThreadRunning(); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unlock the "event" mutex. 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void unlockEventMutex(JdwpState* state) 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgUnlockMutex(&state->eventLock); 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1600970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * Dump an event to the log file. 1610970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden */ 1620970976b0e980be00424f93a69c2bc13ca3131f3Andy McFaddenstatic void dumpEvent(const JdwpEvent* pEvent) 1630970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden{ 1644308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("Event id=0x%4x %p (prev=%p next=%p):", 1650970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden pEvent->requestId, pEvent, pEvent->prev, pEvent->next); 1664308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI(" kind=%s susp=%s modCount=%d", 1670970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden dvmJdwpEventKindStr(pEvent->eventKind), 1680970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden dvmJdwpSuspendPolicyStr(pEvent->suspendPolicy), 1690970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden pEvent->modCount); 1700970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 1712d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < pEvent->modCount; i++) { 1720970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden const JdwpEventMod* pMod = &pEvent->mods[i]; 1732d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpModKind kind = static_cast<JdwpModKind>(pMod->modKind); 1744308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI(" %s", dvmJdwpModKindStr(kind)); 1750970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden /* TODO - show details */ 1760970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } 1770970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden} 1780970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden 1790970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden/* 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Add an event to the list. Ordering is not important. 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If something prevents the event from being registered, e.g. it's a 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * single-step request on a thread that doesn't exist, the event will 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * not be added to the list, and an appropriate error will be returned. 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJdwpError dvmJdwpRegisterEvent(JdwpState* state, JdwpEvent* pEvent) 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockEventMutex(state); 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(state != NULL); 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pEvent != NULL); 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pEvent->prev == NULL); 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pEvent->next == NULL); 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1960970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden * If one or more "break"-type mods are used, register them with 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the interpreter. 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1992d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < pEvent->modCount; i++) { 2000970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden const JdwpEventMod* pMod = &pEvent->mods[i]; 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMod->modKind == MK_LOCATION_ONLY) { 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should only be for Breakpoint, Step, and Exception */ 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgWatchLocation(&pMod->locationOnly.loc); 2040970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else if (pMod->modKind == MK_STEP) { 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should only be for EK_SINGLE_STEP; should only be one */ 2062d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size); 2072d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth); 2082d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro dvmDbgConfigureStep(pMod->step.threadId, size, depth); 2090970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden } else if (pMod->modKind == MK_FIELD_ONLY) { 2100970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden /* should be for EK_FIELD_ACCESS or EK_FIELD_MODIFICATION */ 2110970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden dumpEvent(pEvent); /* TODO - need for field watches */ 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Add to list. 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (state->eventList != NULL) { 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent->next = state->eventList; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->eventList->prev = pEvent; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->eventList = pEvent; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->numEvents++; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unlockEventMutex(state); 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2272d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro return ERR_NONE; 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Remove an event from the list. This will also remove the event from 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * any optimization tables, e.g. breakpoints. 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Does not free the JdwpEvent. 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Grab the eventLock before calling here. 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void unregisterEvent(JdwpState* state, JdwpEvent* pEvent) 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEvent->prev == NULL) { 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* head of the list */ 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(state->eventList == pEvent); 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->eventList = pEvent->next; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent->prev->next = pEvent->next; 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEvent->next != NULL) { 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent->next->prev = pEvent->prev; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent->next = NULL; 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent->prev = NULL; 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unhook us from the interpreter, if necessary. 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2582d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < pEvent->modCount; i++) { 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpEventMod* pMod = &pEvent->mods[i]; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMod->modKind == MK_LOCATION_ONLY) { 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should only be for Breakpoint, Step, and Exception */ 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgUnwatchLocation(&pMod->locationOnly.loc); 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMod->modKind == MK_STEP) { 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* should only be for EK_SINGLE_STEP; should only be one */ 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgUnconfigureStep(pMod->step.threadId); 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->numEvents--; 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(state->numEvents != 0 || state->eventList == NULL); 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Remove the event with the given ID from the list. 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Failure to find the event isn't really an error, but it is a little 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * weird. (It looks like Eclipse will try to be extra careful and will 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * explicitly remove one-off single-step events.) 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmJdwpUnregisterEventById(JdwpState* state, u4 requestId) 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockEventMutex(state); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2852d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpEvent* pEvent = state->eventList; 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (pEvent != NULL) { 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEvent->requestId == requestId) { 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unregisterEvent(state, pEvent); 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpEventFree(pEvent); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto done; /* there can be only one with a given ID */ 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent = pEvent->next; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 296062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block //ALOGD("Odd: no match when removing event reqId=0x%04x", requestId); 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectdone: 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unlockEventMutex(state); 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Remove all entries from the event list. 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmJdwpUnregisterAll(JdwpState* state) 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockEventMutex(state); 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3092d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpEvent* pEvent = state->eventList; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (pEvent != NULL) { 3112d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpEvent* pNextEvent = pEvent->next; 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unregisterEvent(state, pEvent); 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpEventFree(pEvent); 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent = pNextEvent; 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->eventList = NULL; 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unlockEventMutex(state); 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allocate a JdwpEvent struct with enough space to hold the specified 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * number of mod records. 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectJdwpEvent* dvmJdwpEventAlloc(int numMods) 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpEvent* newEvent; 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int allocSize = offsetof(JdwpEvent, mods) + 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numMods * sizeof(newEvent->mods[0]); 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 335b74e7190e86d559712747e5cdb31a0d390b7af7dIliyan Malchev newEvent = (JdwpEvent*)calloc(1, allocSize); 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return newEvent; 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free a JdwpEvent. 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Do not call this until the event has been removed from the list. 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmJdwpEventFree(JdwpEvent* pEvent) 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEvent == NULL) 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* make sure it was removed from the list */ 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pEvent->prev == NULL); 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pEvent->next == NULL); 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* want to assert state->eventList != pEvent */ 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free any hairy bits in the mods. 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3572d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < pEvent->modCount; i++) { 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEvent->mods[i].modKind == MK_CLASS_MATCH) { 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pEvent->mods[i].classMatch.classPattern); 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent->mods[i].classMatch.classPattern = NULL; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) { 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pEvent->mods[i].classExclude.classPattern); 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent->mods[i].classExclude.classPattern = NULL; 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pEvent); 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allocate storage for matching events. To keep things simple we 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * use an array with enough storage for the entire list. 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The state->eventLock should be held before calling. 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic JdwpEvent** allocMatchList(JdwpState* state) 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (JdwpEvent**) malloc(sizeof(JdwpEvent*) * state->numEvents); 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Run through the list and remove any entries with an expired "count" mod 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * from the event list, then free the match list. 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void cleanupMatchList(JdwpState* state, JdwpEvent** matchList, 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int matchCount) 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpEvent** ppEvent = matchList; 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (matchCount--) { 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpEvent* pEvent = *ppEvent; 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3942d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < pEvent->modCount; i++) { 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEvent->mods[i].modKind == MK_COUNT && 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent->mods[i].count.count == 0) 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 39892c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("##### Removing expired event"); 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unregisterEvent(state, pEvent); 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpEventFree(pEvent); 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ppEvent++; 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(matchList); 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Match a string against a "restricted regular expression", which is just 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a string that may start or end with '*' (e.g. "*.Foo" or "java.*"). 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ("Restricted name globbing" might have been a better term.) 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool patternMatch(const char* pattern, const char* target) 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int patLen = strlen(pattern); 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pattern[0] == '*') { 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int targetLen = strlen(target); 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project patLen--; 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // TODO: remove printf when we find a test case to verify this 425c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE(">>> comparing '%s' to '%s'", 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pattern+1, target + (targetLen-patLen)); 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (targetLen < patLen) 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strcmp(pattern+1, target + (targetLen-patLen)) == 0; 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (pattern[patLen-1] == '*') { 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strncmp(pattern, target, patLen-1) == 0; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strcmp(pattern, target) == 0; 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See if two locations are equal. 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It's tempting to do a bitwise compare ("struct ==" or memcmp), but if 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the storage wasn't zeroed out there could be undefined values in the 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * padding. Besides, the odds of "idx" being equal while the others aren't 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is very small, so this is usually just a simple integer comparison. 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline bool locationMatch(const JdwpLocation* pLoc1, 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const JdwpLocation* pLoc2) 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pLoc1->idx == pLoc2->idx && 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc1->methodId == pLoc2->methodId && 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc1->classId == pLoc2->classId && 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pLoc1->typeTag == pLoc2->typeTag; 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See if the event's mods match up with the contents of "basket". 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we find a Count mod before rejecting an event, we decrement it. We 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * need to do this even if later mods cause us to ignore the event. 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool modsMatch(JdwpState* state, JdwpEvent* pEvent, ModBasket* basket) 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project JdwpEventMod* pMod = pEvent->mods; 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4652d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = pEvent->modCount; i > 0; i--, pMod++) { 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (pMod->modKind) { 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_COUNT: 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(pMod->count.count > 0); 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMod->count.count--; 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_CONDITIONAL: 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); // should not be getting these 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_THREAD_ONLY: 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMod->threadOnly.threadId != basket->threadId) 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_CLASS_ONLY: 4790970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (!dvmDbgMatchType(basket->classId, pMod->classOnly.refTypeId)) 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_CLASS_MATCH: 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!patternMatch(pMod->classMatch.classPattern, 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket->className)) 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_CLASS_EXCLUDE: 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (patternMatch(pMod->classMatch.classPattern, 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket->className)) 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_LOCATION_ONLY: 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!locationMatch(&pMod->locationOnly.loc, basket->pLoc)) 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_EXCEPTION_ONLY: 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMod->exceptionOnly.refTypeId != 0 && 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project !dvmDbgMatchType(basket->excepClassId, 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMod->exceptionOnly.refTypeId)) 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((basket->caught && !pMod->exceptionOnly.caught) || 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (!basket->caught && !pMod->exceptionOnly.uncaught)) 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_FIELD_ONLY: 5060970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden if (!dvmDbgMatchType(basket->classId, pMod->fieldOnly.refTypeId) || 5070970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden pMod->fieldOnly.fieldId != basket->field) 5080970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden return false; 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_STEP: 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMod->step.threadId != basket->threadId) 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case MK_INSTANCE_ONLY: 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMod->instanceOnly.objectId != basket->thisPtr) 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 519c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("unhandled mod kind %d", pMod->modKind); 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find all events of type "eventKind" with mods that match up with the 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * rest of the arguments. 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Found events are appended to "matchList", and "*pMatchCount" is advanced, 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * so this may be called multiple times for grouped events. 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DO NOT call this multiple times for the same eventKind, as Count mods are 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * decremented during the scan. 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 538d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostatic void findMatchingEvents(JdwpState* state, JdwpEventKind eventKind, 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ModBasket* basket, JdwpEvent** matchList, int* pMatchCount) 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* start after the existing entries */ 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project matchList += *pMatchCount; 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 5442d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpEvent* pEvent = state->eventList; 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (pEvent != NULL) { 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pEvent->eventKind == eventKind && modsMatch(state, pEvent, basket)) 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *matchList++ = pEvent; 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (*pMatchCount)++; 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pEvent = pEvent->next; 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Scan through the list of matches and determine the most severe 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suspension policy. 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 560d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostatic JdwpSuspendPolicy scanSuspendPolicy(JdwpEvent** matchList, 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int matchCount) 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 563d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro JdwpSuspendPolicy policy = SP_NONE; 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (matchCount--) { 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((*matchList)->suspendPolicy > policy) 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project policy = (*matchList)->suspendPolicy; 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project matchList++; 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return policy; 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Three possibilities: 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * SP_NONE - do nothing 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * SP_EVENT_THREAD - suspend ourselves 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * SP_ALL - suspend everybody except JDWP support thread 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 580d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostatic void suspendByPolicy(JdwpState* state, JdwpSuspendPolicy suspendPolicy) 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspendPolicy == SP_NONE) 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspendPolicy == SP_ALL) { 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgSuspendVM(true); 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(suspendPolicy == SP_EVENT_THREAD); 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* this is rare but possible -- see CLASS_PREPARE handling */ 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dvmDbgGetThreadSelfId() == state->debugThreadId) { 5934308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block ALOGI("NOTE: suspendByPolicy not suspending JDWP thread"); 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DebugInvokeReq* pReq = dvmDbgGetInvokeReq(); 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (true) { 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq->ready = true; 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgSuspendSelf(); 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq->ready = false; 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The JDWP thread has told us (and possibly all other threads) to 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * resume. See if it has left anything in our DebugInvokeReq mailbox. 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!pReq->invokeNeeded) { 60860fc806b679a3655c228b4093058c59941a49cfeDan Bornstein /*LOGD("suspendByPolicy: no invoke needed");*/ 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* grab this before posting/suspending again */ 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSetWaitForEventThread(state, dvmDbgGetThreadSelfId()); 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* leave pReq->invokeNeeded raised so we can check reentrancy */ 61692c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("invoking method..."); 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgExecuteMethod(pReq); 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq->err = ERR_NONE; 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* clear this before signaling */ 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq->invokeNeeded = false; 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62492c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("invoke complete, signaling and self-suspending"); 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgLockMutex(&pReq->lock); 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgCondSignal(&pReq->cv); 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgUnlockMutex(&pReq->lock); 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine if there is a method invocation in progress in the current 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * thread. 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We look at the "invokeNeeded" flag in the per-thread DebugInvokeReq 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * state. If set, we're in the process of invoking a method. 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool invokeInProgress(JdwpState* state) 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DebugInvokeReq* pReq = dvmDbgGetInvokeReq(); 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pReq->invokeNeeded; 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We need the JDWP thread to hold off on doing stuff while we post an 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * event and then suspend ourselves. 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Call this with a threadId of zero if you just want to wait for the 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * current thread operation to complete. 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This could go to sleep waiting for another thread, so it's important 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * that the thread be marked as VMWAIT before calling here. 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmJdwpSetWaitForEventThread(JdwpState* state, ObjectId threadId) 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool waited = false; 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* this is held for very brief periods; contention is unlikely */ 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgLockMutex(&state->eventThreadLock); 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If another thread is already doing stuff, wait for it. This can 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * go to sleep indefinitely. 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (state->eventThreadId != 0) { 66692c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("event in progress (0x%llx), 0x%llx sleeping", 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->eventThreadId, threadId); 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project waited = true; 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgCondWait(&state->eventThreadCond, &state->eventThreadLock); 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (waited || threadId != 0) 67392c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("event token grabbed (0x%llx)", threadId); 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (threadId != 0) 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->eventThreadId = threadId; 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgUnlockMutex(&state->eventThreadLock); 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Clear the threadId and signal anybody waiting. 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmJdwpClearWaitForEventThread(JdwpState* state) 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Grab the mutex. Don't try to go in/out of VMWAIT mode, as this 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * function is called by dvmSuspendSelf(), and the transition back 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to RUNNING would confuse it. 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgLockMutex(&state->eventThreadLock); 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(state->eventThreadId != 0); 69392c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("cleared event token (0x%llx)", state->eventThreadId); 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project state->eventThreadId = 0; 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgCondSignal(&state->eventThreadCond); 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgUnlockMutex(&state->eventThreadLock); 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Prep an event. Allocates storage for the message and leaves space for 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the header. 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 7071e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirostatic ExpandBuf* eventPrep() 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 7092d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro ExpandBuf* pReq = expandBufAlloc(); 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddSpace(pReq, kJDWPHeaderLen); 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pReq; 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Write the header into the buffer and send the packet off to the debugger. 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Takes ownership of "pReq" (currently discards it). 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void eventFinish(JdwpState* state, ExpandBuf* pReq) 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project u1* buf = expandBufGetBuffer(pReq); 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(buf, expandBufGetLength(pReq)); 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set4BE(buf+4, dvmJdwpNextRequestSerial(state)); 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set1(buf+8, 0); /* flags */ 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set1(buf+9, kJdwpEventCommandSet); 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project set1(buf+10, kJdwpCompositeCommand); 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSendRequest(state, pReq); 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufFree(pReq); 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Tell the debugger that we have finished initializing. This is always 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sent, even if the debugger hasn't requested it. 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This should be sent "before the main thread is started and before 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * any application code has been executed". The thread ID in the message 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * must be for the main thread. 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmJdwpPostVMStart(JdwpState* state, bool suspend) 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 746d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro JdwpSuspendPolicy suspendPolicy; 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId threadId = dvmDbgGetThreadSelfId(); 748de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspend) 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendPolicy = SP_ALL; 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendPolicy = SP_NONE; 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* probably don't need this here */ 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockEventMutex(state); 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReq = NULL; 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (true) { 75992c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("EVENT: %s", dvmJdwpEventKindStr(EK_VM_START)); 76092c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" suspendPolicy=%s", dvmJdwpSuspendPolicyStr(suspendPolicy)); 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq = eventPrep(); 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, suspendPolicy); 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, 1); 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, EK_VM_START); 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, 0); /* requestId */ 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReq, threadId); 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unlockEventMutex(state); 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* send request and possibly suspend ourselves */ 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pReq != NULL) { 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int oldStatus = dvmDbgThreadWaiting(); 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspendPolicy != SP_NONE) 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSetWaitForEventThread(state, threadId); 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project eventFinish(state, pReq); 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendByPolicy(state, suspendPolicy); 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgThreadContinuing(oldStatus); 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A location of interest has been reached. This handles: 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Breakpoint 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * SingleStep 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MethodEntry 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MethodExit 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * These four types must be grouped together in a single response. The 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "eventFlags" indicates the type of event(s) that have happened. 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Valid mods: 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * LocationOnly (for breakpoint/step only) 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Step (for step only) 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Interesting test cases: 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - Put a breakpoint on a native method. Eclipse creates METHOD_ENTRY 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and METHOD_EXIT events with a ClassOnly mod on the method's class. 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - Use "run to line". Eclipse creates a BREAKPOINT with Count=1. 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * - Single-step to a line with a breakpoint. Should get a single 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * event message with both events in it. 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmJdwpPostLocationEvent(JdwpState* state, const JdwpLocation* pLoc, 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId thisPtr, int eventFlags) 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 812d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro JdwpSuspendPolicy suspendPolicy = SP_NONE; 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ModBasket basket; 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* nameAlloc = NULL; 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&basket, 0, sizeof(basket)); 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.pLoc = pLoc; 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.classId = pLoc->classId; 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.thisPtr = thisPtr; 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId = dvmDbgGetThreadSelfId(); 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.className = nameAlloc = 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDescriptorToName(dvmDbgGetClassDescriptor(pLoc->classId)); 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * On rare occasions we may need to execute interpreted code in the VM 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * while handling a request from the debugger. Don't fire breakpoints 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * while doing so. (I don't think we currently do this at all, so 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this is mostly paranoia.) 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (basket.threadId == state->debugThreadId) { 83192c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Ignoring location event in JDWP thread"); 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(nameAlloc); 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The debugger variable display tab may invoke the interpreter to format 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * complex objects. We want to ignore breakpoints and method entry/exit 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * traps while working on behalf of the debugger. 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If we don't ignore them, the VM will get hung up, because we'll 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * suspend on a breakpoint while the debugger is still waiting for its 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method invocation to complete. 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (invokeInProgress(state)) { 84692c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Not checking breakpoints during invoke (%s)", basket.className); 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(nameAlloc); 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* don't allow the list to be updated while we scan it */ 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockEventMutex(state); 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8542d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpEvent** matchList = allocMatchList(state); 8552d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro int matchCount = 0; 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((eventFlags & DBG_BREAKPOINT) != 0) 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findMatchingEvents(state, EK_BREAKPOINT, &basket, matchList, 859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &matchCount); 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((eventFlags & DBG_SINGLE_STEP) != 0) 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findMatchingEvents(state, EK_SINGLE_STEP, &basket, matchList, 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &matchCount); 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((eventFlags & DBG_METHOD_ENTRY) != 0) 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findMatchingEvents(state, EK_METHOD_ENTRY, &basket, matchList, 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &matchCount); 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((eventFlags & DBG_METHOD_EXIT) != 0) 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findMatchingEvents(state, EK_METHOD_EXIT, &basket, matchList, 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &matchCount); 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReq = NULL; 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (matchCount != 0) { 87292c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("EVENT: %s(%d total) %s.%s thread=%llx code=%llx)", 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpEventKindStr(matchList[0]->eventKind), matchCount, 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.className, 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgGetMethodName(pLoc->classId, pLoc->methodId), 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId, pLoc->idx); 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendPolicy = scanSuspendPolicy(matchList, matchCount); 87992c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" suspendPolicy=%s", 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSuspendPolicyStr(suspendPolicy)); 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq = eventPrep(); 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, suspendPolicy); 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, matchCount); 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 8862d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < matchCount; i++) { 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, matchList[i]->eventKind); 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, matchList[i]->requestId); 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReq, basket.threadId); 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpAddLocation(pReq, pLoc); 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cleanupMatchList(state, matchList, matchCount); 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unlockEventMutex(state); 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* send request and possibly suspend ourselves */ 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pReq != NULL) { 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int oldStatus = dvmDbgThreadWaiting(); 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspendPolicy != SP_NONE) 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSetWaitForEventThread(state, basket.threadId); 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project eventFinish(state, pReq); 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendByPolicy(state, suspendPolicy); 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgThreadContinuing(oldStatus); 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(nameAlloc); 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return matchCount != 0; 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A thread is starting or stopping. 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Valid mods: 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count, ThreadOnly 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmJdwpPostThreadChange(JdwpState* state, ObjectId threadId, bool start) 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 921d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro JdwpSuspendPolicy suspendPolicy = SP_NONE; 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 923fa76cb555c1683d36ef9d6f6680a0e4e16115679Mark Gordon assert(threadId == dvmDbgGetThreadSelfId()); 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * I don't think this can happen. 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (invokeInProgress(state)) { 929e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("Not posting thread change during invoke"); 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9332d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro ModBasket basket; 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&basket, 0, sizeof(basket)); 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId = threadId; 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* don't allow the list to be updated while we scan it */ 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockEventMutex(state); 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9402d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpEvent** matchList = allocMatchList(state); 9412d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro int matchCount = 0; 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (start) 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findMatchingEvents(state, EK_THREAD_START, &basket, matchList, 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &matchCount); 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findMatchingEvents(state, EK_THREAD_DEATH, &basket, matchList, 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &matchCount); 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReq = NULL; 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (matchCount != 0) { 95292c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("EVENT: %s(%d total) thread=%llx)", 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpEventKindStr(matchList[0]->eventKind), matchCount, 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId); 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendPolicy = scanSuspendPolicy(matchList, matchCount); 95792c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" suspendPolicy=%s", 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSuspendPolicyStr(suspendPolicy)); 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq = eventPrep(); 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, suspendPolicy); 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, matchCount); 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9642d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < matchCount; i++) { 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, matchList[i]->eventKind); 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, matchList[i]->requestId); 967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReq, basket.threadId); 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cleanupMatchList(state, matchList, matchCount); 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unlockEventMutex(state); 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* send request and possibly suspend ourselves */ 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pReq != NULL) { 977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int oldStatus = dvmDbgThreadWaiting(); 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspendPolicy != SP_NONE) 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSetWaitForEventThread(state, basket.threadId); 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project eventFinish(state, pReq); 982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendByPolicy(state, suspendPolicy); 984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgThreadContinuing(oldStatus); 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return matchCount != 0; 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send a polite "VM is dying" message to the debugger. 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Skips the usual "event token" stuff. 994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmJdwpPostVMDeath(JdwpState* state) 996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 99792c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("EVENT: %s", dvmJdwpEventKindStr(EK_VM_DEATH)); 998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9992d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro ExpandBuf* pReq = eventPrep(); 1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, SP_NONE); 1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, 1); 1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, EK_VM_DEATH); 1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, 0); 1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project eventFinish(state, pReq); 1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An exception has been thrown. It may or may not have been caught. 1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Valid mods: 1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly, 1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ExceptionOnly, InstanceOnly 1016c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * 1017c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * The "exceptionId" has not been added to the GC-visible object registry, 1018c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * because there's a pretty good chance that we're not going to send it 1019c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden * up the debugger. 1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmJdwpPostException(JdwpState* state, const JdwpLocation* pThrowLoc, 1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ObjectId exceptionId, RefTypeId exceptionClassId, 1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const JdwpLocation* pCatchLoc, ObjectId thisPtr) 1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1025d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro JdwpSuspendPolicy suspendPolicy = SP_NONE; 1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ModBasket basket; 1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* nameAlloc = NULL; 1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&basket, 0, sizeof(basket)); 1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.pLoc = pThrowLoc; 1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.classId = pThrowLoc->classId; 1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId = dvmDbgGetThreadSelfId(); 1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.className = nameAlloc = 1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDescriptorToName(dvmDbgGetClassDescriptor(basket.classId)); 1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.excepClassId = exceptionClassId; 1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.caught = (pCatchLoc->classId != 0); 1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.thisPtr = thisPtr; 1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* don't try to post an exception caused by the debugger */ 1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (invokeInProgress(state)) { 104192c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Not posting exception hit during invoke (%s)",basket.className); 1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(nameAlloc); 1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* don't allow the list to be updated while we scan it */ 1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockEventMutex(state); 1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 10492d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpEvent** matchList = allocMatchList(state); 10502d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro int matchCount = 0; 1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findMatchingEvents(state, EK_EXCEPTION, &basket, matchList, &matchCount); 1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReq = NULL; 1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (matchCount != 0) { 105692c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("EVENT: %s(%d total) thread=%llx exceptId=%llx caught=%d)", 1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpEventKindStr(matchList[0]->eventKind), matchCount, 1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId, exceptionId, basket.caught); 105992c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" throw: %d %llx %x %lld (%s.%s)", pThrowLoc->typeTag, 1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pThrowLoc->classId, pThrowLoc->methodId, pThrowLoc->idx, 1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgGetClassDescriptor(pThrowLoc->classId), 1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgGetMethodName(pThrowLoc->classId, pThrowLoc->methodId)); 1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pCatchLoc->classId == 0) { 106492c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" catch: (not caught)"); 1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 106692c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" catch: %d %llx %x %lld (%s.%s)", pCatchLoc->typeTag, 1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pCatchLoc->classId, pCatchLoc->methodId, pCatchLoc->idx, 1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgGetClassDescriptor(pCatchLoc->classId), 1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgGetMethodName(pCatchLoc->classId, pCatchLoc->methodId)); 1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendPolicy = scanSuspendPolicy(matchList, matchCount); 107392c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" suspendPolicy=%s", 1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSuspendPolicyStr(suspendPolicy)); 1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq = eventPrep(); 1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, suspendPolicy); 1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, matchCount); 1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 10802d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < matchCount; i++) { 1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, matchList[i]->eventKind); 1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, matchList[i]->requestId); 1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReq, basket.threadId); 1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpAddLocation(pReq, pThrowLoc); 1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, JT_OBJECT); 1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReq, exceptionId); 1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpAddLocation(pReq, pCatchLoc); 1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1090c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden 1091c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden /* don't let the GC discard it */ 1092c6e64ea32a7732e98975e37c5f8545c652a41ac8Andy McFadden dvmDbgRegisterObjectId(exceptionId); 1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cleanupMatchList(state, matchList, matchCount); 1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unlockEventMutex(state); 1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* send request and possibly suspend ourselves */ 1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pReq != NULL) { 1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int oldStatus = dvmDbgThreadWaiting(); 1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspendPolicy != SP_NONE) 1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSetWaitForEventThread(state, basket.threadId); 1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project eventFinish(state, pReq); 1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendByPolicy(state, suspendPolicy); 1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgThreadContinuing(oldStatus); 1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(nameAlloc); 1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return matchCount != 0; 1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Announce that a class has been loaded. 1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Valid mods: 1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude 1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmJdwpPostClassPrepare(JdwpState* state, int tag, RefTypeId refTypeId, 1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* signature, int status) 1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1123d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro JdwpSuspendPolicy suspendPolicy = SP_NONE; 1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ModBasket basket; 1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* nameAlloc = NULL; 1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(&basket, 0, sizeof(basket)); 1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.classId = refTypeId; 1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId = dvmDbgGetThreadSelfId(); 1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.className = nameAlloc = 1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDescriptorToName(dvmDbgGetClassDescriptor(basket.classId)); 1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* suppress class prep caused by debugger */ 1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (invokeInProgress(state)) { 113592c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("Not posting class prep caused by invoke (%s)",basket.className); 1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(nameAlloc); 1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* don't allow the list to be updated while we scan it */ 1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lockEventMutex(state); 1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 11432d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro JdwpEvent** matchList = allocMatchList(state); 11442d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro int matchCount = 0; 1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project findMatchingEvents(state, EK_CLASS_PREPARE, &basket, matchList, 1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project &matchCount); 1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ExpandBuf* pReq = NULL; 1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (matchCount != 0) { 115192c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV("EVENT: %s(%d total) thread=%llx)", 1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpEventKindStr(matchList[0]->eventKind), matchCount, 1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId); 1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendPolicy = scanSuspendPolicy(matchList, matchCount); 115692c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" suspendPolicy=%s", 1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSuspendPolicyStr(suspendPolicy)); 1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (basket.threadId == state->debugThreadId) { 1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * JDWP says that, for a class prep in the debugger thread, we 1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * should set threadId to null and if any threads were supposed 1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to be suspended then we suspend all other threads. 1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 116592c1f6f1b4249e4e379452ee7b49f027052bf4ceSteve Block ALOGV(" NOTE: class prepare in debugger thread!"); 1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project basket.threadId = 0; 1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspendPolicy == SP_EVENT_THREAD) 1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendPolicy = SP_ALL; 1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pReq = eventPrep(); 1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, suspendPolicy); 1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, matchCount); 1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 11752d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < matchCount; i++) { 1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, matchList[i]->eventKind); 1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, matchList[i]->requestId); 1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReq, basket.threadId); 1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd1(pReq, tag); 1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd8BE(pReq, refTypeId); 1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAddUtf8String(pReq, (const u1*) signature); 1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project expandBufAdd4BE(pReq, status); 1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cleanupMatchList(state, matchList, matchCount); 1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unlockEventMutex(state); 1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* send request and possibly suspend ourselves */ 1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pReq != NULL) { 1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int oldStatus = dvmDbgThreadWaiting(); 1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (suspendPolicy != SP_NONE) 1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmJdwpSetWaitForEventThread(state, basket.threadId); 1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project eventFinish(state, pReq); 1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project suspendByPolicy(state, suspendPolicy); 1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmDbgThreadContinuing(oldStatus); 1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(nameAlloc); 1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return matchCount != 0; 1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unload a class. 1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Valid mods: 1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count, ClassMatch, ClassExclude 1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmJdwpPostClassUnload(JdwpState* state, RefTypeId refTypeId) 1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); // TODO 1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Get or set a field. 1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Valid mods: 1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, FieldOnly, 1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * InstanceOnly 1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmJdwpPostFieldAccess(JdwpState* state, int STUFF, ObjectId thisPtr, 12270970976b0e980be00424f93a69c2bc13ca3131f3Andy McFadden bool modified, JValue newValue) 1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(false); // TODO 1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Send up a chunk of DDM data. 1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * While this takes the form of a JDWP "event", it doesn't interact with 1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * other debugger traffic, and can't suspend the VM, so we skip all of 1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the fun event token gymnastics. 1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 12400171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFaddenvoid dvmJdwpDdmSendChunkV(JdwpState* state, int type, const struct iovec* iov, 12410171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden int iovcnt) 1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 12435442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden u1 header[kJDWPHeaderLen + 8]; 12440171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden size_t dataLen = 0; 12450171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden 12460171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden assert(iov != NULL); 12470171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden assert(iovcnt > 0 && iovcnt < 10); 12480171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden 12490171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden /* 12500171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * "Wrap" the contents of the iovec with a JDWP/DDMS header. We do 12510171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden * this by creating a new copy of the vector with space for the header. 12520171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden */ 12530171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden struct iovec wrapiov[iovcnt+1]; 12542d63bc57d5fcbcd54f0bd3e9491e1704b98ec0bfCarl Shapiro for (int i = 0; i < iovcnt; i++) { 12550171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden wrapiov[i+1].iov_base = iov[i].iov_base; 12560171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden wrapiov[i+1].iov_len = iov[i].iov_len; 12570171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden dataLen += iov[i].iov_len; 12580171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden } 12595442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden 12605442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden /* form the header (JDWP plus DDMS) */ 12610171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden set4BE(header, sizeof(header) + dataLen); 12625442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden set4BE(header+4, dvmJdwpNextRequestSerial(state)); 12635442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden set1(header+8, 0); /* flags */ 12645442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden set1(header+9, kJDWPDdmCmdSet); 12655442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden set1(header+10, kJDWPDdmCmd); 12665442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden set4BE(header+11, type); 12670171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden set4BE(header+15, dataLen); 12680171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden 12690171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden wrapiov[0].iov_base = header; 12700171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden wrapiov[0].iov_len = sizeof(header); 12715442d46fe1d0645d786a289c1143e830a6699b14Andy McFadden 12722150b0d21e9db50d76628b6442616489d156b5adAndy McFadden /* 12732150b0d21e9db50d76628b6442616489d156b5adAndy McFadden * Make sure we're in VMWAIT in case the write blocks. 12742150b0d21e9db50d76628b6442616489d156b5adAndy McFadden */ 12752150b0d21e9db50d76628b6442616489d156b5adAndy McFadden int oldStatus = dvmDbgThreadWaiting(); 12760171812e59e2520a4345b9bbadd4f7afa0a1de16Andy McFadden dvmJdwpSendBufferedRequest(state, wrapiov, iovcnt+1); 12772150b0d21e9db50d76628b6442616489d156b5adAndy McFadden dvmDbgThreadContinuing(oldStatus); 1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1279