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