1872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 2872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Copyright (C) 2008 The Android Open Source Project 3872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 4872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * you may not use this file except in compliance with the License. 6872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * You may obtain a copy of the License at 7872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 8872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 10872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Unless required by applicable law or agreed to in writing, software 11872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See the License for the specific language governing permissions and 14872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * limitations under the License. 15872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes 17872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include "jdwp/jdwp_event.h" 18872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include <stddef.h> /* for offsetof() */ 20872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <stdlib.h> 21872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <string.h> 22872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes#include <unistd.h> 23872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 24c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h" 25e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include "art_method-inl.h" 2607ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 27e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h" 2807ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "debugger.h" 2907ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_constants.h" 3007ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_expand_buf.h" 3107ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "jdwp/jdwp_priv.h" 326995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz#include "jdwp/object_registry.h" 336995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz#include "scoped_thread_state_change.h" 34693ff61274cd2c9b8eb7e68c370f84a911b8ca52Ian Rogers#include "thread-inl.h" 3507ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes 36261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz#include "handle_scope-inl.h" 37261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz 38872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 39872d4ec7225444d9400d30f9027247deb91012fdElliott HughesGeneral notes: 40872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 41872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThe event add/remove stuff usually happens from the debugger thread, 42872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesin response to requests from the debugger, but can also happen as the 43872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesresult of an event in an arbitrary thread (e.g. an event with a "count" 44872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesmod expires). It's important to keep the event list locked when processing 45872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesevents. 46872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 47872d4ec7225444d9400d30f9027247deb91012fdElliott HughesEvent posting can happen from any thread. The JDWP thread will not usually 48872d4ec7225444d9400d30f9027247deb91012fdElliott Hughespost anything but VM start/death, but if a JDWP request causes a class 49872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesto be loaded, the ClassPrepare event will come from the JDWP thread. 50872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 51872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 52872d4ec7225444d9400d30f9027247deb91012fdElliott HughesWe can have serialization issues when we post an event to the debugger. 53872d4ec7225444d9400d30f9027247deb91012fdElliott HughesFor example, a thread could send an "I hit a breakpoint and am suspending 54872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesmyself" message to the debugger. Before it manages to suspend itself, the 55872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesdebugger's response ("not interested, resume thread") arrives and is 56872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesprocessed. We try to resume a thread that hasn't yet suspended. 57872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 58872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThis means that, after posting an event to the debugger, we need to wait 59872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesfor the event thread to suspend itself (and, potentially, all other threads) 60872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesbefore processing any additional requests from the debugger. While doing 61872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesso we need to be aware that multiple threads may be hitting breakpoints 62872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesor other events simultaneously, so we either need to wait for all of them 63872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesor serialize the events with each other. 64872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 65872d4ec7225444d9400d30f9027247deb91012fdElliott HughesThe current mechanism works like this: 66872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes Event thread: 67872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - If I'm going to suspend, grab the "I am posting an event" token. Wait 68872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes for it if it's not currently available. 69872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - Post the event to the debugger. 70872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - If appropriate, suspend others and then myself. As part of suspending 71872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes myself, release the "I am posting" token. 72872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes JDWP thread: 73872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - When an event arrives, see if somebody is posting an event. If so, 74872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes sleep until we can acquire the "I am posting an event" token. Release 75872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes it immediately and continue processing -- the event we have already 76872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes received should not interfere with other events that haven't yet 77872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes been posted. 78872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 79872d4ec7225444d9400d30f9027247deb91012fdElliott HughesSome care must be taken to avoid deadlock: 80872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 81872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A and thread B exit near-simultaneously, and post thread-death 82872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes events with a "suspend all" clause 83872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A gets the event token, thread B sits and waits for it 84872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes - thread A wants to suspend all other threads, but thread B is waiting 85872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes for the token and can't be suspended 86872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 87872d4ec7225444d9400d30f9027247deb91012fdElliott HughesSo we need to mark thread B in such a way that thread A doesn't wait for it. 88872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 89872d4ec7225444d9400d30f9027247deb91012fdElliott HughesIf we just bracket the "grab event token" call with a change to VMWAIT 90872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesbefore sleeping, the switch back to RUNNING state when we get the token 91872d4ec7225444d9400d30f9027247deb91012fdElliott Hugheswill cause thread B to suspend (remember, thread A's global suspend is 92872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstill in force, even after it releases the token). Suspending while 93872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesholding the event token is very bad, because it prevents the JDWP thread 94872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesfrom processing incoming messages. 95872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 96872d4ec7225444d9400d30f9027247deb91012fdElliott HughesWe need to change to VMWAIT state at the *start* of posting an event, 97872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesand stay there until we either finish posting the event or decide to 98872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesput ourselves to sleep. That way we don't interfere with anyone else and 99872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesdon't allow anyone else to interfere with us. 100872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes*/ 101872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 102872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace art { 103872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 104872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesnamespace JDWP { 105872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 106872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 107872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Stuff to compare against when deciding if a mod matches. Only the 108872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * values for mods valid for the event being evaluated will be filled in. 109872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The rest will be zeroed. 110261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz * Must be allocated on the stack only. This is enforced by removing the 111261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz * operator new. 112872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 113872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstruct ModBasket { 114261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz explicit ModBasket(Thread* self) 115261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz : hs(self), pLoc(nullptr), thread(self), 116261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz locationClass(hs.NewHandle<mirror::Class>(nullptr)), 117261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz exceptionClass(hs.NewHandle<mirror::Class>(nullptr)), 118261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz caught(false), 119261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz field(nullptr), 120261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz thisPtr(hs.NewHandle<mirror::Object>(nullptr)) { } 121261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz 122261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz StackHandleScope<3> hs; 123261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz const EventLocation* pLoc; /* LocationOnly */ 124261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz std::string className; /* ClassMatch/ClassExclude */ 125261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz Thread* const thread; /* ThreadOnly */ 126261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz MutableHandle<mirror::Class> locationClass; /* ClassOnly */ 127261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz MutableHandle<mirror::Class> exceptionClass; /* ExceptionOnly */ 128261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz bool caught; /* ExceptionOnly */ 129261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz ArtField* field; /* FieldOnly */ 130261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz MutableHandle<mirror::Object> thisPtr; /* InstanceOnly */ 131872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* nothing for StepOnly -- handled differently */ 132261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz 133261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz private: 134261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz DISALLOW_ALLOCATION(); // forbids allocation on the heap. 135261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz DISALLOW_IMPLICIT_CONSTRUCTORS(ModBasket); 136872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes}; 137872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 138138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertzstatic bool NeedsFullDeoptimization(JdwpEventKind eventKind) { 139f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz if (!Dbg::RequiresDeoptimization()) { 140f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz // We don't need deoptimization for debugging. 141f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz return false; 142f3928794a10516e2ac0ffe2686a10891788d4b9cSebastien Hertz } 143138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz switch (eventKind) { 144138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz case EK_METHOD_ENTRY: 145138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz case EK_METHOD_EXIT: 146138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz case EK_METHOD_EXIT_WITH_RETURN_VALUE: 1473f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz case EK_FIELD_ACCESS: 1483f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz case EK_FIELD_MODIFICATION: 149138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz return true; 150138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz default: 151138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz return false; 152138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz } 153138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz} 154138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 1559d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz// Returns the instrumentation event the DebugInstrumentationListener must 1569d6bf69ad3012a9d843268fdd5325b6719b6d5f2Sebastien Hertz// listen to in order to properly report the given JDWP event to the debugger. 157277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic uint32_t GetInstrumentationEventFor(JdwpEventKind eventKind) { 15842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz switch (eventKind) { 15942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_BREAKPOINT: 16042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_SINGLE_STEP: 16142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz return instrumentation::Instrumentation::kDexPcMoved; 16242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_EXCEPTION: 16342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_EXCEPTION_CATCH: 16442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz return instrumentation::Instrumentation::kExceptionCaught; 16542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_METHOD_ENTRY: 16642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz return instrumentation::Instrumentation::kMethodEntered; 16742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_METHOD_EXIT: 16842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_METHOD_EXIT_WITH_RETURN_VALUE: 16942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz return instrumentation::Instrumentation::kMethodExited; 17042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_FIELD_ACCESS: 17142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz return instrumentation::Instrumentation::kFieldRead; 17242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz case EK_FIELD_MODIFICATION: 17342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz return instrumentation::Instrumentation::kFieldWritten; 17442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz default: 17542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz return 0; 17642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz } 17742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz} 17842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz 179872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 180872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Add an event to the list. Ordering is not important. 181872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 182872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If something prevents the event from being registered, e.g. it's a 183872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * single-step request on a thread that doesn't exist, the event will 184872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * not be added to the list, and an appropriate error will be returned. 185872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 186761928d24e4e7ed7776b52243eaf9095ad35f448Elliott HughesJdwpError JdwpState::RegisterEvent(JdwpEvent* pEvent) { 1877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CHECK(pEvent != nullptr); 1887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CHECK(pEvent->prev == nullptr); 1897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CHECK(pEvent->next == nullptr); 190872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 19142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz { 19242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz /* 19342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz * If one or more "break"-type mods are used, register them with 19442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz * the interpreter. 19542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz */ 19642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz DeoptimizationRequest req; 19742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz for (int i = 0; i < pEvent->modCount; i++) { 19842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz const JdwpEventMod* pMod = &pEvent->mods[i]; 19942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz if (pMod->modKind == MK_LOCATION_ONLY) { 200033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz // Should only concern breakpoint, field access, field modification, step, and exception 201033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz // events. 202033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz // However breakpoint requires specific handling. Field access, field modification and step 203033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz // events need full deoptimization to be reported while exception event is reported during 204033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz // exception handling. 205033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz if (pEvent->eventKind == EK_BREAKPOINT) { 206033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz Dbg::WatchLocation(&pMod->locationOnly.loc, &req); 207033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz } 20842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz } else if (pMod->modKind == MK_STEP) { 20942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz /* should only be for EK_SINGLE_STEP; should only be one */ 21042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz JdwpStepSize size = static_cast<JdwpStepSize>(pMod->step.size); 21142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz JdwpStepDepth depth = static_cast<JdwpStepDepth>(pMod->step.depth); 21242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz JdwpError status = Dbg::ConfigureStep(pMod->step.threadId, size, depth); 21342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz if (status != ERR_NONE) { 21442cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz return status; 21542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz } 2162435a5751431152aaeaa2faaa86b2a30d3eecfe3Elliott Hughes } 217872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 21842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz if (NeedsFullDeoptimization(pEvent->eventKind)) { 2190ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing); 2200ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi CHECK(req.Method() == nullptr); 2210ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi req.SetKind(DeoptimizationRequest::kFullDeoptimization); 22242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz } 22342cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz Dbg::RequestDeoptimization(req); 224872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 22542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind); 22642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz if (instrumentation_event != 0) { 22742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz DeoptimizationRequest req; 2280ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi req.SetKind(DeoptimizationRequest::kRegisterForEvent); 2290ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi req.SetInstrumentationEvent(instrumentation_event); 23042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz Dbg::RequestDeoptimization(req); 2314d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz } 232872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 233138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz { 234138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz /* 235138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz * Add to list. 236138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz */ 237138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 2387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (event_list_ != nullptr) { 239138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz pEvent->next = event_list_; 240138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz event_list_->prev = pEvent; 241138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz } 242138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz event_list_ = pEvent; 243138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz ++event_list_size_; 244872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 245138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 246138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz Dbg::ManageDeoptimization(); 247872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 248872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return ERR_NONE; 249872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 250872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 251872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 252872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove an event from the list. This will also remove the event from 253872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any optimization tables, e.g. breakpoints. 254872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 255872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Does not free the JdwpEvent. 256872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 257872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Grab the eventLock before calling here. 258872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 259761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEvent(JdwpEvent* pEvent) { 2607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (pEvent->prev == nullptr) { 261872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* head of the list */ 262f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes CHECK(event_list_ == pEvent); 263872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 264f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes event_list_ = pEvent->next; 265872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } else { 266872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes pEvent->prev->next = pEvent->next; 267872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 268872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 2697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (pEvent->next != nullptr) { 270872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes pEvent->next->prev = pEvent->prev; 2717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz pEvent->next = nullptr; 272872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 2737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz pEvent->prev = nullptr; 274872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 27542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz { 27642cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz /* 27742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz * Unhook us from the interpreter, if necessary. 27842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz */ 27942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz DeoptimizationRequest req; 28042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz for (int i = 0; i < pEvent->modCount; i++) { 28142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz JdwpEventMod* pMod = &pEvent->mods[i]; 28242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz if (pMod->modKind == MK_LOCATION_ONLY) { 283033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz // Like in RegisterEvent, we need specific handling for breakpoint only. 284033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz if (pEvent->eventKind == EK_BREAKPOINT) { 285033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz Dbg::UnwatchLocation(&pMod->locationOnly.loc, &req); 286033aabf9789eda162e183ed34678d665dc903387Sebastien Hertz } 28742cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz } 28842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz if (pMod->modKind == MK_STEP) { 28942cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz /* should only be for EK_SINGLE_STEP; should only be one */ 29042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz Dbg::UnconfigureStep(pMod->step.threadId); 29142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz } 292872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 293eb07669e9784ccb41d75df180727e57fc4520e28Daniel Mihalyi if (NeedsFullDeoptimization(pEvent->eventKind)) { 2940ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi CHECK_EQ(req.GetKind(), DeoptimizationRequest::kNothing); 2950ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi CHECK(req.Method() == nullptr); 2960ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi req.SetKind(DeoptimizationRequest::kFullUndeoptimization); 297872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 29842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz Dbg::RequestDeoptimization(req); 299872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 30042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz uint32_t instrumentation_event = GetInstrumentationEventFor(pEvent->eventKind); 30142cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz if (instrumentation_event != 0) { 30242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz DeoptimizationRequest req; 3030ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi req.SetKind(DeoptimizationRequest::kUnregisterForEvent); 3040ec17d2ddb69d3f5c46ccad62e82c0ffd6219428Hiroshi Yamauchi req.SetInstrumentationEvent(instrumentation_event); 30542cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz Dbg::RequestDeoptimization(req); 3064d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz } 307872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 308f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes --event_list_size_; 3097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CHECK(event_list_size_ != 0 || event_list_ == nullptr); 310872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 311872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 312872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 313872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove the event with the given ID from the list. 314872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 315872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 316761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterEventById(uint32_t requestId) { 317138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz bool found = false; 318138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz { 319138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 320872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 321138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) { 322138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz if (pEvent->requestId == requestId) { 323138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz found = true; 324138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz UnregisterEvent(pEvent); 325138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz EventFree(pEvent); 326138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz break; /* there can be only one with a given ID */ 327138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz } 328872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 329872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 330872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 331138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz if (found) { 332138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz Dbg::ManageDeoptimization(); 333138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz } else { 334f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz // Failure to find the event isn't really an error. For instance, it looks like Eclipse will 335f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz // try to be extra careful and will explicitly remove one-off single-step events (using a 336f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz // 'count' event modifier of 1). So the event may have already been removed as part of the 337f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz // event notification (see JdwpState::CleanupMatchList). 338f272af4b9dcd39cdd50fa6655601a26e837eaea9Sebastien Hertz VLOG(jdwp) << StringPrintf("No match when removing event reqId=0x%04x", requestId); 339138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz } 340872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 341872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 342872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 343872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Remove all entries from the event list. 344872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 345761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::UnregisterAll() { 34650b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers MutexLock mu(Thread::Current(), event_list_lock_); 347872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 348f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes JdwpEvent* pEvent = event_list_; 3497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz while (pEvent != nullptr) { 350872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes JdwpEvent* pNextEvent = pEvent->next; 351872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 352761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes UnregisterEvent(pEvent); 353872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes EventFree(pEvent); 354872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes pEvent = pNextEvent; 355872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 356872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 3577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz event_list_ = nullptr; 358872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 359872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 360872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 361872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Allocate a JdwpEvent struct with enough space to hold the specified 362872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * number of mod records. 363872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 364872d4ec7225444d9400d30f9027247deb91012fdElliott HughesJdwpEvent* EventAlloc(int numMods) { 365872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes JdwpEvent* newEvent; 366872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes int allocSize = offsetof(JdwpEvent, mods) + numMods * sizeof(newEvent->mods[0]); 367872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes newEvent = reinterpret_cast<JdwpEvent*>(malloc(allocSize)); 368872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes memset(newEvent, 0, allocSize); 369872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return newEvent; 370872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 371872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 372872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 373872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Free a JdwpEvent. 374872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 375872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Do not call this until the event has been removed from the list. 376872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 377872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesvoid EventFree(JdwpEvent* pEvent) { 3787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (pEvent == nullptr) { 379872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return; 380872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 381872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 382872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* make sure it was removed from the list */ 3837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CHECK(pEvent->prev == nullptr); 3847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CHECK(pEvent->next == nullptr); 385f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes /* want to check state->event_list_ != pEvent */ 386872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 387872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 388872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Free any hairy bits in the mods. 389872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 390872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes for (int i = 0; i < pEvent->modCount; i++) { 391872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes if (pEvent->mods[i].modKind == MK_CLASS_MATCH) { 392872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes free(pEvent->mods[i].classMatch.classPattern); 3937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz pEvent->mods[i].classMatch.classPattern = nullptr; 394872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 395872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes if (pEvent->mods[i].modKind == MK_CLASS_EXCLUDE) { 396872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes free(pEvent->mods[i].classExclude.classPattern); 3977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz pEvent->mods[i].classExclude.classPattern = nullptr; 398872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 399872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 400872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 401872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes free(pEvent); 402872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 403872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 404872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 405872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Run through the list and remove any entries with an expired "count" mod 4067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * from the event list. 407872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 4087d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::CleanupMatchList(const std::vector<JdwpEvent*>& match_list) { 4097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (JdwpEvent* pEvent : match_list) { 4107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (int i = 0; i < pEvent->modCount; ++i) { 411872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes if (pEvent->mods[i].modKind == MK_COUNT && pEvent->mods[i].count.count == 0) { 412bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz VLOG(jdwp) << StringPrintf("##### Removing expired event (requestId=%#" PRIx32 ")", 413bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz pEvent->requestId); 414761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes UnregisterEvent(pEvent); 415872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes EventFree(pEvent); 416872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 417872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 418872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 419872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 420872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 421872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 422872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 423872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Match a string against a "restricted regular expression", which is just 424872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * a string that may start or end with '*' (e.g. "*.Foo" or "java.*"). 425872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 426872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * ("Restricted name globbing" might have been a better term.) 427872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 428761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesstatic bool PatternMatch(const char* pattern, const std::string& target) { 429a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes size_t patLen = strlen(pattern); 430872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes if (pattern[0] == '*') { 431872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes patLen--; 432a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes if (target.size() < patLen) { 433872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 434872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 435a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes return strcmp(pattern+1, target.c_str() + (target.size()-patLen)) == 0; 436872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } else if (pattern[patLen-1] == '*') { 437a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes return strncmp(pattern, target.c_str(), patLen-1) == 0; 438872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } else { 439a215526d5c789cbef0f81a1f9aba22541a841ccaElliott Hughes return strcmp(pattern, target.c_str()) == 0; 440872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 441872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 442872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 443872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 444872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * See if the event's mods match up with the contents of "basket". 445872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 446872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If we find a Count mod before rejecting an event, we decrement it. We 447872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * need to do this even if later mods cause us to ignore the event. 448872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 449bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertzstatic bool ModsMatch(JdwpEvent* pEvent, const ModBasket& basket) 45090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 451872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes JdwpEventMod* pMod = pEvent->mods; 452872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 453872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes for (int i = pEvent->modCount; i > 0; i--, pMod++) { 454872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes switch (pMod->modKind) { 455872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_COUNT: 456872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes CHECK_GT(pMod->count.count, 0); 457872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes pMod->count.count--; 45843207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz if (pMod->count.count > 0) { 45943207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz return false; 46043207797d05e54fb945e2fc22145722cb26cb27bSebastien Hertz } 461872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 462872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_CONDITIONAL: 463872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes CHECK(false); // should not be getting these 464872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 465872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_THREAD_ONLY: 4666995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz if (!Dbg::MatchThread(pMod->threadOnly.threadId, basket.thread)) { 467872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 468872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 469872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 470872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_CLASS_ONLY: 471261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz if (!Dbg::MatchType(basket.locationClass.Get(), pMod->classOnly.refTypeId)) { 472872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 473872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 474872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 475872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_CLASS_MATCH: 476bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz if (!PatternMatch(pMod->classMatch.classPattern, basket.className)) { 477872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 478872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 479872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 480872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_CLASS_EXCLUDE: 481bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz if (PatternMatch(pMod->classMatch.classPattern, basket.className)) { 482872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 483872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 484872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 485872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_LOCATION_ONLY: 4866995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz if (!Dbg::MatchLocation(pMod->locationOnly.loc, *basket.pLoc)) { 487872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 488872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 489872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 490872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_EXCEPTION_ONLY: 4916995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz if (pMod->exceptionOnly.refTypeId != 0 && 492261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz !Dbg::MatchType(basket.exceptionClass.Get(), pMod->exceptionOnly.refTypeId)) { 493872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 494872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 4956995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz if ((basket.caught && !pMod->exceptionOnly.caught) || 4966995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz (!basket.caught && !pMod->exceptionOnly.uncaught)) { 497872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 498872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 499872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 500872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_FIELD_ONLY: 5016995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz if (!Dbg::MatchField(pMod->fieldOnly.refTypeId, pMod->fieldOnly.fieldId, basket.field)) { 502872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 503872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 504872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 505872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_STEP: 5066995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz if (!Dbg::MatchThread(pMod->step.threadId, basket.thread)) { 507872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 508872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 509872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 510872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes case MK_INSTANCE_ONLY: 511261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz if (!Dbg::MatchInstance(pMod->instanceOnly.objectId, basket.thisPtr.Get())) { 512872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return false; 513872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 514872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 515872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes default: 5167b3cdfcca472b779cf8745fb8460935e56229f11Elliott Hughes LOG(FATAL) << "unknown mod kind " << pMod->modKind; 517872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 518872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 519872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 520872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return true; 521872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 522872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 523872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 5247d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Find all events of type "event_kind" with mods that match up with the 5257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * rest of the arguments while holding the event list lock. This method 5267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * is used by FindMatchingEvents below. 527872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 5287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Found events are appended to "match_list" so this may be called multiple times for grouped 5297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * events. 530872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 531872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * DO NOT call this multiple times for the same eventKind, as Count mods are 532872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * decremented during the scan. 533872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 5347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::FindMatchingEventsLocked(JdwpEventKind event_kind, const ModBasket& basket, 5357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::vector<JdwpEvent*>* match_list) { 536bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz for (JdwpEvent* pEvent = event_list_; pEvent != nullptr; pEvent = pEvent->next) { 5377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (pEvent->eventKind == event_kind && ModsMatch(pEvent, basket)) { 5387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz match_list->push_back(pEvent); 539872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 540872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 541872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 542872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 543872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 5447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Find all events of type "event_kind" with mods that match up with the 5457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * rest of the arguments and return true if at least one event matches, 5467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * false otherwise. 5477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * 5487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * Found events are appended to "match_list" so this may be called multiple 5497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * times for grouped events. 5507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * 5517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * DO NOT call this multiple times for the same eventKind, as Count mods are 5527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * decremented during the scan. 5537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz */ 5547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzbool JdwpState::FindMatchingEvents(JdwpEventKind event_kind, const ModBasket& basket, 5557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::vector<JdwpEvent*>* match_list) { 5567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 5577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz match_list->reserve(event_list_size_); 5587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz FindMatchingEventsLocked(event_kind, basket, match_list); 5597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return !match_list->empty(); 5607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz} 5617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 5627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz/* 563872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Scan through the list of matches and determine the most severe 564872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * suspension policy. 565872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 5667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzstatic JdwpSuspendPolicy ScanSuspendPolicy(const std::vector<JdwpEvent*>& match_list) { 567872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes JdwpSuspendPolicy policy = SP_NONE; 568872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 5697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (JdwpEvent* pEvent : match_list) { 5707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (pEvent->suspend_policy > policy) { 5717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz policy = pEvent->suspend_policy; 572872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 573872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 574872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 575872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return policy; 576872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 577872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 578872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 579872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Three possibilities: 580872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * SP_NONE - do nothing 581872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * SP_EVENT_THREAD - suspend ourselves 582872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * SP_ALL - suspend everybody except JDWP support thread 583872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 58400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SuspendByPolicy(JdwpSuspendPolicy suspend_policy, JDWP::ObjectId thread_self_id) { 585f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes VLOG(jdwp) << "SuspendByPolicy(" << suspend_policy << ")"; 586f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes if (suspend_policy == SP_NONE) { 587872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return; 588872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 589872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 590f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes if (suspend_policy == SP_ALL) { 591475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes Dbg::SuspendVM(); 592872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } else { 593f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes CHECK_EQ(suspend_policy, SP_EVENT_THREAD); 594872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 595872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 596872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* this is rare but possible -- see CLASS_PREPARE handling */ 59700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers if (thread_self_id == debug_thread_id_) { 598761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes LOG(INFO) << "NOTE: SuspendByPolicy not suspending JDWP thread"; 599872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return; 600872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 601872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 602872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes while (true) { 603872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes Dbg::SuspendSelf(); 604872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 605872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 606872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The JDWP thread has told us (and possibly all other threads) to 607872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * resume. See if it has left anything in our DebugInvokeReq mailbox. 608872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 6091558b577907b613864e98f05862543557263e864Sebastien Hertz DebugInvokeReq* const pReq = Dbg::GetInvokeReq(); 6101558b577907b613864e98f05862543557263e864Sebastien Hertz if (pReq == nullptr) { 611872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes break; 612872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 613872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 614cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz // Execute method. 615872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes Dbg::ExecuteMethod(pReq); 616872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 617872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 618872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 61900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersvoid JdwpState::SendRequestAndPossiblySuspend(ExpandBuf* pReq, JdwpSuspendPolicy suspend_policy, 62000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers ObjectId threadId) { 6217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz Thread* const self = Thread::Current(); 62200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers self->AssertThreadSuspensionIsAllowable(); 6237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CHECK(pReq != nullptr); 62400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers /* send request and possibly suspend ourselves */ 6257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JDWP::ObjectId thread_self_id = Dbg::GetThreadSelfId(); 626f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier ScopedThreadSuspension sts(self, kWaitingForDebuggerSend); 6277d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (suspend_policy != SP_NONE) { 6282bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz AcquireJdwpTokenForEvent(threadId); 62900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 6307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz EventFinish(pReq); 631813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz { 632813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz // Before suspending, we change our state to kSuspended so the debugger sees us as RUNNING. 633813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz ScopedThreadStateChange stsc(self, kSuspended); 634813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz SuspendByPolicy(suspend_policy, thread_self_id); 635813b9602dadeabf33439cb0592072744f6241ce5Sebastien Hertz } 63600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers} 63700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 638872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 639872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Determine if there is a method invocation in progress in the current 640872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * thread. 641872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 642475fc23a4a7f35d1be87ea0b06c80df317a720acElliott Hughes * We look at the "invoke_needed" flag in the per-thread DebugInvokeReq 643872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * state. If set, we're in the process of invoking a method. 644872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 645761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesbool JdwpState::InvokeInProgress() { 646872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes DebugInvokeReq* pReq = Dbg::GetInvokeReq(); 6471558b577907b613864e98f05862543557263e864Sebastien Hertz return pReq != nullptr; 648872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 649872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 6502bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::AcquireJdwpTokenForCommand() { 6512bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread"; 6522bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz SetWaitForJdwpToken(debug_thread_id_); 6532bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz} 6542bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz 6552bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ReleaseJdwpTokenForCommand() { 6562bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_EQ(Thread::Current(), GetDebugThread()) << "Expected debugger thread"; 6572bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz ClearWaitForJdwpToken(); 6582bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz} 6592bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz 6602bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::AcquireJdwpTokenForEvent(ObjectId threadId) { 6612bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_NE(Thread::Current(), GetDebugThread()) << "Expected event thread"; 6622bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_NE(debug_thread_id_, threadId) << "Not expected debug thread"; 6632bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz SetWaitForJdwpToken(threadId); 6642bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz} 6652bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz 6662bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ReleaseJdwpTokenForEvent() { 6672bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_NE(Thread::Current(), GetDebugThread()) << "Expected event thread"; 6682bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz ClearWaitForJdwpToken(); 6692bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz} 6702bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz 671872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 672872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * We need the JDWP thread to hold off on doing stuff while we post an 673872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * event and then suspend ourselves. 674872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 675872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This could go to sleep waiting for another thread, so it's important 676872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * that the thread be marked as VMWAIT before calling here. 677872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 6782bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::SetWaitForJdwpToken(ObjectId threadId) { 679872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes bool waited = false; 6802bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz Thread* const self = Thread::Current(); 6812bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_NE(threadId, 0u); 6822bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_NE(self->GetState(), kRunnable); 6832bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz Locks::mutator_lock_->AssertNotHeld(self); 684872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 685872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* this is held for very brief periods; contention is unlikely */ 6862bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz MutexLock mu(self, jdwp_token_lock_); 6872bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz 6882bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_NE(jdwp_token_owner_thread_id_, threadId) << "Thread is already holding event thread lock"; 689872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 690872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 691872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If another thread is already doing stuff, wait for it. This can 692872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * go to sleep indefinitely. 693872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 6942bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz while (jdwp_token_owner_thread_id_ != 0) { 695d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers VLOG(jdwp) << StringPrintf("event in progress (%#" PRIx64 "), %#" PRIx64 " sleeping", 6962bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz jdwp_token_owner_thread_id_, threadId); 697872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes waited = true; 6982bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz jdwp_token_cond_.Wait(self); 699872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 700872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 7012bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz if (waited || threadId != debug_thread_id_) { 702d9e4e0c8606f8b87e0a48aab68125dbee543bf88Ian Rogers VLOG(jdwp) << StringPrintf("event token grabbed (%#" PRIx64 ")", threadId); 703872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 7042bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz jdwp_token_owner_thread_id_ = threadId; 705872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 706872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 707872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 708872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Clear the threadId and signal anybody waiting. 709872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 7102bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertzvoid JdwpState::ClearWaitForJdwpToken() { 711872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 712872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Grab the mutex. Don't try to go in/out of VMWAIT mode, as this 7132bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz * function is called by Dbg::SuspendSelf(), and the transition back 714872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * to RUNNING would confuse it. 715872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 7162bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz Thread* const self = Thread::Current(); 7172bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz MutexLock mu(self, jdwp_token_lock_); 718872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 7192bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz CHECK_NE(jdwp_token_owner_thread_id_, 0U); 7202bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz VLOG(jdwp) << StringPrintf("cleared event token (%#" PRIx64 ")", jdwp_token_owner_thread_id_); 721872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 7222bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz jdwp_token_owner_thread_id_ = 0; 7232bf93f48bbb417b358c9e3c77911ea6ec7307c15Sebastien Hertz jdwp_token_cond_.Signal(self); 724872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 725872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 726872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 727872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Prep an event. Allocates storage for the message and leaves space for 728872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the header. 729872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 730872d4ec7225444d9400d30f9027247deb91012fdElliott Hughesstatic ExpandBuf* eventPrep() { 731872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes ExpandBuf* pReq = expandBufAlloc(); 732872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAddSpace(pReq, kJDWPHeaderLen); 733872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return pReq; 734872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 735872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 736872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 737872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Write the header into the buffer and send the packet off to the debugger. 738872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 739872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Takes ownership of "pReq" (currently discards it). 740872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 741761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughesvoid JdwpState::EventFinish(ExpandBuf* pReq) { 742872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes uint8_t* buf = expandBufGetBuffer(pReq); 743872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 744cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set4BE(buf + kJDWPHeaderSizeOffset, expandBufGetLength(pReq)); 745cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set4BE(buf + kJDWPHeaderIdOffset, NextRequestSerial()); 746cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set1(buf + kJDWPHeaderFlagsOffset, 0); /* flags */ 747cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set1(buf + kJDWPHeaderCmdSetOffset, kJDWPEventCmdSet); 748cbc5064ff05179b97b416f00ca579c55e38cd7d9Sebastien Hertz Set1(buf + kJDWPHeaderCmdOffset, kJDWPEventCompositeCmd); 749872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 750761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes SendRequest(pReq); 751872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 752872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufFree(pReq); 753872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 754872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 755872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 756872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 757872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Tell the debugger that we have finished initializing. This is always 758872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * sent, even if the debugger hasn't requested it. 759872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 760872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * This should be sent "before the main thread is started and before 761872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * any application code has been executed". The thread ID in the message 762872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * must be for the main thread. 763872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 7647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostVMStart() { 7657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JdwpSuspendPolicy suspend_policy = (options_->suspend) ? SP_ALL : SP_NONE; 766872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes ObjectId threadId = Dbg::GetThreadSelfId(); 767872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 7687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << "EVENT: " << EK_VM_START; 7697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " suspend_policy=" << suspend_policy; 770872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 771761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes ExpandBuf* pReq = eventPrep(); 7727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, suspend_policy); 7737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, 1); 7747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, EK_VM_START); 7757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, 0); /* requestId */ 7767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddObjectId(pReq, threadId); 777872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 778138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz Dbg::ManageDeoptimization(); 779138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 780872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* send request and possibly suspend ourselves */ 78100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers SendRequestAndPossiblySuspend(pReq, suspend_policy, threadId); 782872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 783872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 7847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzstatic void LogMatchingEventsAndThread(const std::vector<JdwpEvent*> match_list, 7856995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz ObjectId thread_id) 78690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 7877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (size_t i = 0, e = match_list.size(); i < e; ++i) { 788bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz JdwpEvent* pEvent = match_list[i]; 789bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz VLOG(jdwp) << "EVENT #" << i << ": " << pEvent->eventKind 790bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz << StringPrintf(" (requestId=%#" PRIx32 ")", pEvent->requestId); 791bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz } 792bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz std::string thread_name; 7936995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz JdwpError error = Dbg::GetThreadName(thread_id, &thread_name); 794bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz if (error != JDWP::ERR_NONE) { 795bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz thread_name = "<unknown>"; 796bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz } 7976995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz VLOG(jdwp) << StringPrintf(" thread=%#" PRIx64, thread_id) << " " << thread_name; 7986995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz} 7996995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz 8006995c60cd6657c10811055c42661a55b10b47cefSebastien Hertzstatic void SetJdwpLocationFromEventLocation(const JDWP::EventLocation* event_location, 8016995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz JDWP::JdwpLocation* jdwp_location) 80290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 8036995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(event_location != nullptr); 8046995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(jdwp_location != nullptr); 8056995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz Dbg::SetJdwpLocation(jdwp_location, event_location->method, event_location->dex_pc); 806bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz} 807bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz 808872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 809872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A location of interest has been reached. This handles: 810872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Breakpoint 811872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * SingleStep 812872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * MethodEntry 813872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * MethodExit 814872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * These four types must be grouped together in a single response. The 815872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * "eventFlags" indicates the type of event(s) that have happened. 816872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 817872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods: 818872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, InstanceOnly 819872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * LocationOnly (for breakpoint/step only) 820872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Step (for step only) 821872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 822872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Interesting test cases: 823872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * - Put a breakpoint on a native method. Eclipse creates METHOD_ENTRY 824872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * and METHOD_EXIT events with a ClassOnly mod on the method's class. 825872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * - Use "run to line". Eclipse creates a BREAKPOINT with Count=1. 826872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * - Single-step to a line with a breakpoint. Should get a single 827872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * event message with both events in it. 828872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 8297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thisPtr, 8306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz int eventFlags, const JValue* returnValue) { 8316995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(pLoc != nullptr); 8326995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(pLoc->method != nullptr); 8336995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK_EQ(pLoc->method->IsStatic(), thisPtr == nullptr); 8346995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz 835261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz ModBasket basket(Thread::Current()); 836872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes basket.pLoc = pLoc; 837261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.locationClass.Assign(pLoc->method->GetDeclaringClass()); 838261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.thisPtr.Assign(thisPtr); 839261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.className = Dbg::GetClassName(basket.locationClass.Get()); 840872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 841872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 842872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * On rare occasions we may need to execute interpreted code in the VM 843872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * while handling a request from the debugger. Don't fire breakpoints 844872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * while doing so. (I don't think we currently do this at all, so 845872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * this is mostly paranoia.) 846872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 8476995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz if (basket.thread == GetDebugThread()) { 8484dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jdwp) << "Ignoring location event in JDWP thread"; 8497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 850872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 851872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 852872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 853872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The debugger variable display tab may invoke the interpreter to format 854872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * complex objects. We want to ignore breakpoints and method entry/exit 855872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * traps while working on behalf of the debugger. 856872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 857872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * If we don't ignore them, the VM will get hung up, because we'll 858872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * suspend on a breakpoint while the debugger is still waiting for its 859872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * method invocation to complete. 860872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 861761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes if (InvokeInProgress()) { 8624dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jdwp) << "Not checking breakpoints during invoke (" << basket.className << ")"; 8637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 864872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 865872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 8667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::vector<JdwpEvent*> match_list; 867761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes { 8687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // We use the locked version because we have multiple possible match events. 8697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 8707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz match_list.reserve(event_list_size_); 8717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if ((eventFlags & Dbg::kBreakpoint) != 0) { 8727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz FindMatchingEventsLocked(EK_BREAKPOINT, basket, &match_list); 873761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes } 8747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if ((eventFlags & Dbg::kSingleStep) != 0) { 8757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz FindMatchingEventsLocked(EK_SINGLE_STEP, basket, &match_list); 8767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 8777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if ((eventFlags & Dbg::kMethodEntry) != 0) { 8787d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz FindMatchingEventsLocked(EK_METHOD_ENTRY, basket, &match_list); 8797d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 8807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if ((eventFlags & Dbg::kMethodExit) != 0) { 8817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz FindMatchingEventsLocked(EK_METHOD_EXIT, basket, &match_list); 8827d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz FindMatchingEventsLocked(EK_METHOD_EXIT_WITH_RETURN_VALUE, basket, &match_list); 8837d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 8847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 8857d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (match_list.empty()) { 8867d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // No matching event. 8877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 8887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 8897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 890bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz 8917d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectId thread_id = Dbg::GetThreadId(basket.thread); 8927d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JDWP::JdwpLocation jdwp_location; 8937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz SetJdwpLocationFromEventLocation(pLoc, &jdwp_location); 8946995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz 8957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (VLOG_IS_ON(jdwp)) { 8967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz LogMatchingEventsAndThread(match_list, thread_id); 8977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " location=" << jdwp_location; 8987d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " suspend_policy=" << suspend_policy; 8997d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 900872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 9017d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ExpandBuf* pReq = eventPrep(); 9027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, suspend_policy); 9037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, match_list.size()); 9047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 9057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (const JdwpEvent* pEvent : match_list) { 9067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, pEvent->eventKind); 9077d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, pEvent->requestId); 9087d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddObjectId(pReq, thread_id); 9097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddLocation(pReq, jdwp_location); 9107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (pEvent->eventKind == EK_METHOD_EXIT_WITH_RETURN_VALUE) { 9117d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz Dbg::OutputMethodReturnValue(jdwp_location.method_id, returnValue, pReq); 912872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 9137d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 914872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 9157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 9167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 9177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CleanupMatchList(match_list); 918761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes } 919872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 920138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz Dbg::ManageDeoptimization(); 921138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 9226995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 923872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 924872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 925c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartiervoid JdwpState::PostFieldEvent(const EventLocation* pLoc, ArtField* field, 9266995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz mirror::Object* this_object, const JValue* fieldValue, 9276995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz bool is_modification) { 9286995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(pLoc != nullptr); 9296995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(field != nullptr); 9306995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK_EQ(fieldValue != nullptr, is_modification); 9316995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK_EQ(field->IsStatic(), this_object == nullptr); 9326995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz 933261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz ModBasket basket(Thread::Current()); 9343f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz basket.pLoc = pLoc; 935261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.locationClass.Assign(pLoc->method->GetDeclaringClass()); 936261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.thisPtr.Assign(this_object); 937261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.className = Dbg::GetClassName(basket.locationClass.Get()); 9386995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz basket.field = field; 939bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz 9403f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz if (InvokeInProgress()) { 941261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz VLOG(jdwp) << "Not posting field event during invoke (" << basket.className << ")"; 9427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 9433f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz } 9443f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 9457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::vector<JdwpEvent*> match_list; 9467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz const JdwpEventKind match_kind = (is_modification) ? EK_FIELD_MODIFICATION : EK_FIELD_ACCESS; 9477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (!FindMatchingEvents(match_kind, basket, &match_list)) { 9487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // No matching event. 9497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 9507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 9513f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 9527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 9537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectId thread_id = Dbg::GetThreadId(basket.thread); 9547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectRegistry* registry = Dbg::GetObjectRegistry(); 9557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectId instance_id = registry->Add(basket.thisPtr); 9567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz RefTypeId field_type_id = registry->AddRefType(field->GetDeclaringClass()); 9577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz FieldId field_id = Dbg::ToFieldId(field); 9587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JDWP::JdwpLocation jdwp_location; 9597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz SetJdwpLocationFromEventLocation(pLoc, &jdwp_location); 9607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 9617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (VLOG_IS_ON(jdwp)) { 9627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz LogMatchingEventsAndThread(match_list, thread_id); 9637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " location=" << jdwp_location; 9647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << StringPrintf(" this=%#" PRIx64, instance_id); 9657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << StringPrintf(" type=%#" PRIx64, field_type_id) << " " 9667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz << Dbg::GetClassName(field_id); 967d3ed9a320a89cb9b91b2361892c043ab7e112717Mathieu Chartier VLOG(jdwp) << StringPrintf(" field=%#" PRIx64, field_id) << " " 9687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz << Dbg::GetFieldName(field_id); 9697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " suspend_policy=" << suspend_policy; 9707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 9713f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 9727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ExpandBuf* pReq = eventPrep(); 9737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, suspend_policy); 9747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, match_list.size()); 9756995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz 9767d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // Get field's reference type tag. 9777d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JDWP::JdwpTypeTag type_tag = Dbg::GetTypeTag(field->GetDeclaringClass()); 9786995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz 9797d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // Get instance type tag. 9807d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz uint8_t tag; 9817d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 9827d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ScopedObjectAccessUnchecked soa(Thread::Current()); 983261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz tag = Dbg::TagFromObject(soa, basket.thisPtr.Get()); 9847d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 9853f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 9867d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (const JdwpEvent* pEvent : match_list) { 9877d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, pEvent->eventKind); 9887d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, pEvent->requestId); 9897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddObjectId(pReq, thread_id); 9907d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddLocation(pReq, jdwp_location); 9917d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, type_tag); 9927d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddRefTypeId(pReq, field_type_id); 9937d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddFieldId(pReq, field_id); 9947d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, tag); 9957d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddObjectId(pReq, instance_id); 9967d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (is_modification) { 9977d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz Dbg::OutputFieldValue(field_id, fieldValue, pReq); 9986995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz } 9993f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz } 10003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 10017d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 10027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 10037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CleanupMatchList(match_list); 10047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 10057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 10063f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz Dbg::ManageDeoptimization(); 10073f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 10086995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 10093f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz} 10103f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 1011872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1012872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * A thread is starting or stopping. 1013872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1014872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods: 1015872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Count, ThreadOnly 1016872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 10177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostThreadChange(Thread* thread, bool start) { 10186995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz CHECK_EQ(thread, Thread::Current()); 1019872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1020872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 1021872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * I don't think this can happen. 1022872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1023761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes if (InvokeInProgress()) { 1024872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes LOG(WARNING) << "Not posting thread change during invoke"; 10257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 1026872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1027872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1028107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz // We need the java.lang.Thread object associated to the starting/ending 1029107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz // thread to get its JDWP id. Therefore we can't report event if there 1030107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz // is no Java peer. This happens when the runtime shuts down and re-attaches 1031107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz // the current thread without creating a Java peer. 1032107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz if (thread->GetPeer() == nullptr) { 1033107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz return; 1034107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz } 1035107e757bfd32cc27750955e6f392986414bebe75Sebastien Hertz 1036261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz ModBasket basket(thread); 1037872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 10387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::vector<JdwpEvent*> match_list; 10397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz const JdwpEventKind match_kind = (start) ? EK_THREAD_START : EK_THREAD_DEATH; 10407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (!FindMatchingEvents(match_kind, basket, &match_list)) { 10417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // No matching event. 10427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 10437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 1044bca0d3d0279e9a75b4aec827b40cdb267e1e990eSebastien Hertz 10457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 10467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectId thread_id = Dbg::GetThreadId(basket.thread); 10476995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz 10487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (VLOG_IS_ON(jdwp)) { 10497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz LogMatchingEventsAndThread(match_list, thread_id); 10507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " suspend_policy=" << suspend_policy; 10517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 1052872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 10537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ExpandBuf* pReq = eventPrep(); 10547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, suspend_policy); 10557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, match_list.size()); 1056234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes 10577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (const JdwpEvent* pEvent : match_list) { 10587d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, pEvent->eventKind); 10597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, pEvent->requestId); 10607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd8BE(pReq, thread_id); 10617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 1062872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 10637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 10647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 10657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CleanupMatchList(match_list); 1066234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes } 1067872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1068138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz Dbg::ManageDeoptimization(); 1069138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 10706995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 1071872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1072872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1073872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1074872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send a polite "VM is dying" message to the debugger. 1075872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1076872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Skips the usual "event token" stuff. 1077872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1078376a7a033d29d5f2b6e16574a340c999ff2999a0Elliott Hughesbool JdwpState::PostVMDeath() { 10794dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jdwp) << "EVENT: " << EK_VM_DEATH; 1080872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1081872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes ExpandBuf* pReq = eventPrep(); 1082872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd1(pReq, SP_NONE); 1083872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReq, 1); 1084872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1085872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd1(pReq, EK_VM_DEATH); 1086872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes expandBufAdd4BE(pReq, 0); 1087761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes EventFinish(pReq); 1088872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes return true; 1089872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1090872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1091872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1092872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * An exception has been thrown. It may or may not have been caught. 1093872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1094872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods: 1095872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude, LocationOnly, 1096872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * ExceptionOnly, InstanceOnly 1097872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1098872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * The "exceptionId" has not been added to the GC-visible object registry, 1099872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * because there's a pretty good chance that we're not going to send it 1100872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * up the debugger. 1101872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 11027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostException(const EventLocation* pThrowLoc, mirror::Throwable* exception_object, 11036995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz const EventLocation* pCatchLoc, mirror::Object* thisPtr) { 11046995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(exception_object != nullptr); 11056995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(pThrowLoc != nullptr); 11066995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(pCatchLoc != nullptr); 1107a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz if (pThrowLoc->method != nullptr) { 1108a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz DCHECK_EQ(pThrowLoc->method->IsStatic(), thisPtr == nullptr); 1109a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz } else { 1110a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz VLOG(jdwp) << "Unexpected: exception event with empty throw location"; 1111a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz } 1112872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1113261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz ModBasket basket(Thread::Current()); 1114872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes basket.pLoc = pThrowLoc; 1115a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz if (pThrowLoc->method != nullptr) { 1116261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.locationClass.Assign(pThrowLoc->method->GetDeclaringClass()); 1117a9aa0ffc2cf917be05749d1b27e7994249edb6d2Sebastien Hertz } 1118261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.className = Dbg::GetClassName(basket.locationClass.Get()); 1119261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.exceptionClass.Assign(exception_object->GetClass()); 11206995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz basket.caught = (pCatchLoc->method != 0); 1121261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.thisPtr.Assign(thisPtr); 1122872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1123872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* don't try to post an exception caused by the debugger */ 1124761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes if (InvokeInProgress()) { 11254dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jdwp) << "Not posting exception hit during invoke (" << basket.className << ")"; 11267d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 1127872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1128872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 11297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::vector<JdwpEvent*> match_list; 11307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (!FindMatchingEvents(EK_EXCEPTION, basket, &match_list)) { 11317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // No matching event. 11327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 11337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 1134872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 11357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 11367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectId thread_id = Dbg::GetThreadId(basket.thread); 11377d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectRegistry* registry = Dbg::GetObjectRegistry(); 11387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectId exceptionId = registry->Add(exception_object); 11397d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JDWP::JdwpLocation jdwp_throw_location; 11407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JDWP::JdwpLocation jdwp_catch_location; 11417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz SetJdwpLocationFromEventLocation(pThrowLoc, &jdwp_throw_location); 11427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz SetJdwpLocationFromEventLocation(pCatchLoc, &jdwp_catch_location); 11437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 11447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (VLOG_IS_ON(jdwp)) { 11457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::string exceptionClassName(PrettyDescriptor(exception_object->GetClass())); 11467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 11477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz LogMatchingEventsAndThread(match_list, thread_id); 11487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " throwLocation=" << jdwp_throw_location; 11497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (jdwp_catch_location.class_id == 0) { 11507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " catchLocation=uncaught"; 11517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } else { 11527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " catchLocation=" << jdwp_catch_location; 1153872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 11547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << StringPrintf(" exception=%#" PRIx64, exceptionId) << " " 11557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz << exceptionClassName; 11567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " suspend_policy=" << suspend_policy; 11577d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 1158872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 11597d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ExpandBuf* pReq = eventPrep(); 11607d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, suspend_policy); 11617d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, match_list.size()); 11627d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 11637d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (const JdwpEvent* pEvent : match_list) { 11647d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, pEvent->eventKind); 11657d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, pEvent->requestId); 11667d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddObjectId(pReq, thread_id); 11677d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddLocation(pReq, jdwp_throw_location); 11687d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, JT_OBJECT); 11697d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddObjectId(pReq, exceptionId); 11707d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddLocation(pReq, jdwp_catch_location); 11717d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 11727d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 11737d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 11747d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 11757d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CleanupMatchList(match_list); 1176872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1177872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1178138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz Dbg::ManageDeoptimization(); 1179138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 11806995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 1181872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1182872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1183872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1184872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Announce that a class has been loaded. 1185872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1186872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Valid mods: 1187872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Count, ThreadOnly, ClassOnly, ClassMatch, ClassExclude 1188872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 11897d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertzvoid JdwpState::PostClassPrepare(mirror::Class* klass) { 11906995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz DCHECK(klass != nullptr); 1191872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1192261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz ModBasket basket(Thread::Current()); 1193261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.locationClass.Assign(klass); 1194261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz basket.className = Dbg::GetClassName(basket.locationClass.Get()); 1195872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1196872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* suppress class prep caused by debugger */ 1197761928d24e4e7ed7776b52243eaf9095ad35f448Elliott Hughes if (InvokeInProgress()) { 11984dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes VLOG(jdwp) << "Not posting class prep caused by invoke (" << basket.className << ")"; 11997d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 1200872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1201872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 12027d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::vector<JdwpEvent*> match_list; 12037d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (!FindMatchingEvents(EK_CLASS_PREPARE, basket, &match_list)) { 12047d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // No matching event. 12057d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz return; 12067d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 1207872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 12087d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz JdwpSuspendPolicy suspend_policy = ScanSuspendPolicy(match_list); 12097d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectId thread_id = Dbg::GetThreadId(basket.thread); 12107d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ObjectRegistry* registry = Dbg::GetObjectRegistry(); 12117d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz RefTypeId class_id = registry->AddRefType(basket.locationClass); 12127d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 12137d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // OLD-TODO - we currently always send both "verified" and "prepared" since 12147d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // debuggers seem to like that. There might be some advantage to honesty, 12157d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz // since the class may not yet be verified. 12167d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz int status = JDWP::CS_VERIFIED | JDWP::CS_PREPARED; 1217261bc044a3575512869586593e99e97cd8b1c321Sebastien Hertz JDWP::JdwpTypeTag tag = Dbg::GetTypeTag(basket.locationClass.Get()); 12187d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::string temp; 12197d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz std::string signature(basket.locationClass->GetDescriptor(&temp)); 12207d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 12217d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (VLOG_IS_ON(jdwp)) { 12227d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz LogMatchingEventsAndThread(match_list, thread_id); 12237d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << StringPrintf(" type=%#" PRIx64, class_id) << " " << signature; 12247d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " suspend_policy=" << suspend_policy; 12257d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 1226872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 12277d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (thread_id == debug_thread_id_) { 12287d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz /* 12297d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * JDWP says that, for a class prep in the debugger thread, we 12307d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * should set thread to null and if any threads were supposed 12317d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz * to be suspended then we suspend all other threads. 12327d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz */ 12337d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz VLOG(jdwp) << " NOTE: class prepare in debugger thread!"; 12347d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz thread_id = 0; 12357d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (suspend_policy == SP_EVENT_THREAD) { 12367d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz suspend_policy = SP_ALL; 1237872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 12387d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 12396995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz 12407d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz ExpandBuf* pReq = eventPrep(); 12417d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, suspend_policy); 12427d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, match_list.size()); 12437d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 12447d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz for (const JdwpEvent* pEvent : match_list) { 12457d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, pEvent->eventKind); 12467d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, pEvent->requestId); 12477d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddObjectId(pReq, thread_id); 12487d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd1(pReq, tag); 12497d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddRefTypeId(pReq, class_id); 12507d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAddUtf8String(pReq, signature); 12517d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz expandBufAdd4BE(pReq, status); 12527d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz } 12537d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz 12547d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz { 12557d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz MutexLock mu(Thread::Current(), event_list_lock_); 12567d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CleanupMatchList(match_list); 1257872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1258872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1259138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz Dbg::ManageDeoptimization(); 1260138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 12616995c60cd6657c10811055c42661a55b10b47cefSebastien Hertz SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id); 1262872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1263872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1264872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes/* 1265ad466adf38db74a9840659626858196091151a64Mathieu Chartier * Setup the header for a chunk of DDM data. 1266ad466adf38db74a9840659626858196091151a64Mathieu Chartier */ 1267ad466adf38db74a9840659626858196091151a64Mathieu Chartiervoid JdwpState::SetupChunkHeader(uint32_t type, size_t data_len, size_t header_size, 1268ad466adf38db74a9840659626858196091151a64Mathieu Chartier uint8_t* out_header) { 1269ad466adf38db74a9840659626858196091151a64Mathieu Chartier CHECK_EQ(header_size, static_cast<size_t>(kJDWPHeaderLen + 8)); 1270ad466adf38db74a9840659626858196091151a64Mathieu Chartier /* form the header (JDWP plus DDMS) */ 1271ad466adf38db74a9840659626858196091151a64Mathieu Chartier Set4BE(out_header, header_size + data_len); 1272ad466adf38db74a9840659626858196091151a64Mathieu Chartier Set4BE(out_header + 4, NextRequestSerial()); 1273ad466adf38db74a9840659626858196091151a64Mathieu Chartier Set1(out_header + 8, 0); /* flags */ 1274ad466adf38db74a9840659626858196091151a64Mathieu Chartier Set1(out_header + 9, kJDWPDdmCmdSet); 1275ad466adf38db74a9840659626858196091151a64Mathieu Chartier Set1(out_header + 10, kJDWPDdmCmd); 1276ad466adf38db74a9840659626858196091151a64Mathieu Chartier Set4BE(out_header + 11, type); 1277ad466adf38db74a9840659626858196091151a64Mathieu Chartier Set4BE(out_header + 15, data_len); 1278ad466adf38db74a9840659626858196091151a64Mathieu Chartier} 1279ad466adf38db74a9840659626858196091151a64Mathieu Chartier 1280ad466adf38db74a9840659626858196091151a64Mathieu Chartier/* 1281872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * Send up a chunk of DDM data. 1282872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * 1283872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * While this takes the form of a JDWP "event", it doesn't interact with 1284872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * other debugger traffic, and can't suspend the VM, so we skip all of 1285872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * the fun event token gymnastics. 1286872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1287cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughesvoid JdwpState::DdmSendChunkV(uint32_t type, const iovec* iov, int iov_count) { 1288ad466adf38db74a9840659626858196091151a64Mathieu Chartier uint8_t header[kJDWPHeaderLen + 8] = { 0 }; 1289872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes size_t dataLen = 0; 1290872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 12917d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz CHECK(iov != nullptr); 1292cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes CHECK_GT(iov_count, 0); 1293cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes CHECK_LT(iov_count, 10); 1294872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1295872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes /* 1296872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * "Wrap" the contents of the iovec with a JDWP/DDMS header. We do 1297872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes * this by creating a new copy of the vector with space for the header. 1298872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes */ 1299f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom std::vector<iovec> wrapiov; 1300f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom wrapiov.push_back(iovec()); 1301cccd84f1f972f1a260c3be418c8388a5d30cf59eElliott Hughes for (int i = 0; i < iov_count; i++) { 1302f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom wrapiov.push_back(iov[i]); 1303872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes dataLen += iov[i].iov_len; 1304872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes } 1305872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1306ad466adf38db74a9840659626858196091151a64Mathieu Chartier SetupChunkHeader(type, dataLen, sizeof(header), header); 1307872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1308872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes wrapiov[0].iov_base = header; 1309872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes wrapiov[0].iov_len = sizeof(header); 1310872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 131115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers // Try to avoid blocking GC during a send, but only safe when not using mutexes at a lower-level 131215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers // than mutator for lock ordering reasons. 131300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Thread* self = Thread::Current(); 131462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool safe_to_release_mutator_lock_over_send = !Locks::mutator_lock_->IsExclusiveHeld(self); 131562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers if (safe_to_release_mutator_lock_over_send) { 131638f85e4892f6504971bde994fec81fd61780ac30Brian Carlstrom for (size_t i = 0; i < kMutatorLock; ++i) { 13177d95565c84d91ae5dcec4b89728ada208633de0cSebastien Hertz if (self->GetHeldMutex(static_cast<LockLevel>(i)) != nullptr) { 131862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers safe_to_release_mutator_lock_over_send = false; 131962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers break; 132062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 132115bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers } 132215bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers } 132315bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers if (safe_to_release_mutator_lock_over_send) { 132415bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers // Change state to waiting to allow GC, ... while we're sending. 1325f1d666e1b48f8070ef1177fce156c08827f08eb8Mathieu Chartier ScopedThreadSuspension sts(self, kWaitingForDebuggerSend); 1326f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom SendBufferedRequest(type, wrapiov); 132715bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers } else { 132815bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers // Send and possibly block GC... 1329f52935278fca8c7aa220543eef4544e3d1105d91Brian Carlstrom SendBufferedRequest(type, wrapiov); 133015bf2d34efa2218e287b584fb3653d268b9edc8dIan Rogers } 1331872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} 1332872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1333872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} // namespace JDWP 1334872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes 1335872d4ec7225444d9400d30f9027247deb91012fdElliott Hughes} // namespace art 1336