1
/*******************************************************************************
2
* Copyright (c) 2000, 2009 QNX Software Systems and others.
3
* All rights reserved. This program and the accompanying materials
4
* are made available under the terms of the Eclipse Public License v1.0
5
* which accompanies this distribution, and is available at
6
* http://www.eclipse.org/legal/epl-v10.html
9
* QNX Software Systems - Initial API and implementation
10
* Alena Laskavaia (QNX) - Bug 197986, Bug 221224
11
*******************************************************************************/
12
package org.eclipse.cdt.debug.mi.core.cdi;
14
import java.util.ArrayList;
15
import java.util.Collections;
16
import java.util.Hashtable;
17
import java.util.Iterator;
18
import java.util.List;
21
import org.eclipse.cdt.debug.core.cdi.CDIException;
22
import org.eclipse.cdt.debug.core.cdi.model.ICDIArgumentDescriptor;
23
import org.eclipse.cdt.debug.core.cdi.model.ICDILocalVariableDescriptor;
24
import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame;
25
import org.eclipse.cdt.debug.core.cdi.model.ICDIThread;
26
import org.eclipse.cdt.debug.core.cdi.model.ICDIThreadStorageDescriptor;
27
import org.eclipse.cdt.debug.core.cdi.model.ICDIVariable;
28
import org.eclipse.cdt.debug.mi.core.MIException;
29
import org.eclipse.cdt.debug.mi.core.MISession;
30
import org.eclipse.cdt.debug.mi.core.RxThread;
31
import org.eclipse.cdt.debug.mi.core.cdi.model.Argument;
32
import org.eclipse.cdt.debug.mi.core.cdi.model.ArgumentDescriptor;
33
import org.eclipse.cdt.debug.mi.core.cdi.model.GlobalVariable;
34
import org.eclipse.cdt.debug.mi.core.cdi.model.GlobalVariableDescriptor;
35
import org.eclipse.cdt.debug.mi.core.cdi.model.LocalVariable;
36
import org.eclipse.cdt.debug.mi.core.cdi.model.LocalVariableDescriptor;
37
import org.eclipse.cdt.debug.mi.core.cdi.model.Register;
38
import org.eclipse.cdt.debug.mi.core.cdi.model.RegisterDescriptor;
39
import org.eclipse.cdt.debug.mi.core.cdi.model.StackFrame;
40
import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
41
import org.eclipse.cdt.debug.mi.core.cdi.model.Thread;
42
import org.eclipse.cdt.debug.mi.core.cdi.model.ThreadStorage;
43
import org.eclipse.cdt.debug.mi.core.cdi.model.ThreadStorageDescriptor;
44
import org.eclipse.cdt.debug.mi.core.cdi.model.Variable;
45
import org.eclipse.cdt.debug.mi.core.cdi.model.VariableDescriptor;
46
import org.eclipse.cdt.debug.mi.core.command.CLIPType;
47
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
48
import org.eclipse.cdt.debug.mi.core.command.MIStackListArguments;
49
import org.eclipse.cdt.debug.mi.core.command.MIStackListLocals;
50
import org.eclipse.cdt.debug.mi.core.command.MIVarCreate;
51
import org.eclipse.cdt.debug.mi.core.command.MIVarDelete;
52
import org.eclipse.cdt.debug.mi.core.command.MIVarUpdate;
53
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
54
import org.eclipse.cdt.debug.mi.core.event.MIVarChangedEvent;
55
import org.eclipse.cdt.debug.mi.core.event.MIVarDeletedEvent;
56
import org.eclipse.cdt.debug.mi.core.output.CLIPTypeInfo;
57
import org.eclipse.cdt.debug.mi.core.output.MIArg;
58
import org.eclipse.cdt.debug.mi.core.output.MIFrame;
59
import org.eclipse.cdt.debug.mi.core.output.MIStackListArgumentsInfo;
60
import org.eclipse.cdt.debug.mi.core.output.MIStackListLocalsInfo;
61
import org.eclipse.cdt.debug.mi.core.output.MIVar;
62
import org.eclipse.cdt.debug.mi.core.output.MIVarChange;
63
import org.eclipse.cdt.debug.mi.core.output.MIVarCreateInfo;
64
import org.eclipse.cdt.debug.mi.core.output.MIVarUpdateInfo;
68
public class VariableManager extends Manager {
70
static final ICDIVariable[] EMPTY_VARIABLES = {};
71
// We put a restriction on how deep we want to
72
// go when doing update of the variables.
73
// If the number is to high, gdb will just hang.
74
int MAX_STACK_DEPTH = Thread.STACKFRAME_DEFAULT_DEPTH;
76
MIVarChange[] noChanges = new MIVarChange[0];
78
public VariableManager(Session session) {
80
variablesMap = new Hashtable();
83
synchronized List getVariablesList(Target target) {
84
List variablesList = (List) variablesMap.get(target);
85
if (variablesList == null) {
86
variablesList = Collections.synchronizedList(new ArrayList());
87
variablesMap.put(target, variablesList);
93
* Return the element that have the uniq varName.
94
* null is return if the element is not in the cache.
96
public Variable getVariable(MISession miSession, String varName) {
97
Target target = ((Session)getSession()).getTarget(miSession);
98
return getVariable(target, varName);
102
* Return the element that have the uniq varName.
103
* null is return if the element is not in the cache.
105
public Variable getVariable(Target target, String varName) {
106
Variable[] vars = getVariables(target);
107
for (int i = 0; i < vars.length; i++) {
109
if (vars[i].getMIVar().getVarName().equals(varName)) {
112
Variable v = vars[i].getChild(varName);
116
} catch (CDIException e) {
124
* Return the Element with this thread/stackframe, and with this name.
125
* null is return if the element is not in the cache.
127
Variable findVariable(VariableDescriptor v) throws CDIException {
128
Target target = (Target)v.getTarget();
129
ICDIStackFrame vstack = v.getStackFrame();
130
ICDIThread vthread = v.getThread();
131
int position = v.getPosition();
132
int depth = v.getStackDepth();
133
Variable[] vars = getVariables(target);
134
for (int i = 0; i < vars.length; i++) {
135
if (vars[i].getFullName().equals(v.getFullName())
136
&& vars[i].getName().equals(v.getName()) // see bug #113364
137
&& vars[i].getCastingArrayStart() == v.getCastingArrayStart()
138
&& vars[i].getCastingArrayEnd() == v.getCastingArrayEnd()
139
&& VariableDescriptor.equalsCasting(vars[i], v)) {
141
ICDIThread thread = vars[i].getThread();
142
if ((vthread == null && thread == null) ||
143
(vthread != null && thread != null && thread.equals(vthread))) {
145
ICDIStackFrame frame = vars[i].getStackFrame();
146
if (vstack == null && frame == null) {
148
} else if (frame != null && vstack != null && frame.equals(vstack)) {
149
if (vars[i].getPosition() == position) {
150
if (vars[i].getStackDepth() == depth) {
162
* Returns all the elements that are in the cache.
164
Variable[] getVariables(Target target) {
165
List variableList = (List)variablesMap.get(target);
166
if (variableList != null) {
167
return (Variable[]) variableList.toArray(new Variable[variableList.size()]);
169
return new Variable[0];
175
public void checkType(StackFrame frame, String type) throws CDIException {
176
if (type != null && type.length() > 0) {
177
Target target = (Target)frame.getTarget();
178
Thread currentThread = (Thread)target.getCurrentThread();
179
StackFrame currentFrame = currentThread.getCurrentStackFrame();
180
synchronized(target.getLock()) {
182
target.setCurrentThread(frame.getThread(), false);
183
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
184
MISession miSession = target.getMISession();
185
RxThread rxThread = miSession.getRxThread();
186
rxThread.setEnableConsole(false);
187
CommandFactory factory = miSession.getCommandFactory();
188
CLIPType ptype = factory.createCLIPType(type);
189
miSession.postCommand(ptype);
190
CLIPTypeInfo info = ptype.getMIPtypeInfo();
192
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
194
} catch (MIException e) {
195
throw new MI2CDIException(e);
197
MISession miSession = target.getMISession();
198
RxThread rxThread = miSession.getRxThread();
199
rxThread.setEnableConsole(true);
200
target.setCurrentThread(currentThread, false);
201
currentThread.setCurrentStackFrame(currentFrame, false);
205
throw new CDIException(CdiResources.getString("cdi.VariableManager.Unknown_type")); //$NON-NLS-1$
210
* Tell gdb to remove the underlying var-object also.
212
void removeMIVar(MISession miSession, MIVar miVar) throws CDIException {
213
CommandFactory factory = miSession.getCommandFactory();
214
MIVarDelete var = factory.createMIVarDelete(miVar.getVarName());
216
miSession.postCommand(var);
218
} catch (MIException e) {
219
throw new MI2CDIException(e);
224
* Remove variable form the maintained cache list.
229
public Variable removeVariableFromList(MISession miSession, String varName) {
230
Target target = ((Session)getSession()).getTarget(miSession);
231
List varList = getVariablesList(target);
232
synchronized (varList) {
233
for (Iterator iterator = varList.iterator(); iterator.hasNext();) {
234
Variable variable = (Variable)iterator.next();
236
if (variable.getMIVar().getVarName().equals(varName)) {
240
} catch (CDIException e) {
249
* Encode the variableDescriptor as an array
254
* @throws CDIException
256
public VariableDescriptor getVariableDescriptorAsArray(VariableDescriptor varDesc, int start, int length)
257
throws CDIException {
258
Target target = (Target)varDesc.getTarget();
259
Thread thread = (Thread)varDesc.getThread();
260
StackFrame frame = (StackFrame)varDesc.getStackFrame();
261
String name = varDesc.getName();
262
String fullName = varDesc.getFullName();
263
int pos = varDesc.getPosition();
264
int depth = varDesc.getStackDepth();
265
VariableDescriptor vo = null;
267
if (varDesc instanceof ArgumentDescriptor || varDesc instanceof Argument) {
268
vo = new ArgumentDescriptor(target, thread, frame, name, fullName, pos, depth);
269
} else if (varDesc instanceof LocalVariableDescriptor || varDesc instanceof LocalVariable) {
270
vo = new LocalVariableDescriptor(target, thread, frame, name, fullName, pos, depth);
271
} else if (varDesc instanceof GlobalVariableDescriptor || varDesc instanceof GlobalVariable) {
272
vo = new GlobalVariableDescriptor(target, thread, frame, name, fullName, pos, depth);
273
} else if (varDesc instanceof RegisterDescriptor || varDesc instanceof Register) {
274
vo = new RegisterDescriptor(target, thread, frame, name, fullName, pos, depth);
275
} else if (varDesc instanceof ThreadStorageDescriptor || varDesc instanceof ThreadStorage) {
276
vo = new ThreadStorageDescriptor(target, thread, frame, name, fullName, pos, depth);
278
throw new CDIException(CdiResources.getString("cdi.VariableManager.Unknown_variable_object")); //$NON-NLS-1$
281
vo.setCastingArrayStart(varDesc.getCastingArrayStart() + start);
282
vo.setCastingArrayEnd(length);
287
* Encode the variableDescriptor in a typecasting.
291
* @throws CDIException
293
public VariableDescriptor getVariableDescriptorAsType(VariableDescriptor varDesc, String type) throws CDIException {
294
// throw an exception if not a good type.
295
Target target = (Target)varDesc.getTarget();
296
Thread thread = (Thread)varDesc.getThread();
297
StackFrame frame = (StackFrame)varDesc.getStackFrame();
298
String name = varDesc.getName();
299
String fullName = varDesc.getFullName();
300
int pos = varDesc.getPosition();
301
int depth = varDesc.getStackDepth();
303
// Check the type validity.
305
StackFrame f = frame;
307
if (thread != null) {
308
f = thread.getCurrentStackFrame();
310
Thread t = (Thread)target.getCurrentThread();
311
f = t.getCurrentStackFrame();
317
VariableDescriptor vo = null;
319
if (varDesc instanceof ArgumentDescriptor || varDesc instanceof Argument) {
320
vo = new ArgumentDescriptor(target, thread, frame, name, fullName, pos, depth);
321
} else if (varDesc instanceof LocalVariableDescriptor || varDesc instanceof LocalVariable) {
322
vo = new LocalVariableDescriptor(target, thread, frame, name, fullName, pos, depth);
323
} else if (varDesc instanceof GlobalVariableDescriptor || varDesc instanceof GlobalVariable) {
324
vo = new GlobalVariableDescriptor(target, thread, frame, name, fullName, pos, depth);
325
} else if (varDesc instanceof ThreadStorageDescriptor || varDesc instanceof ThreadStorage) {
326
vo = new ThreadStorageDescriptor(target, thread, frame, name, fullName, pos, depth);
327
} else if (varDesc instanceof RegisterDescriptor || varDesc instanceof Register) {
328
vo = new RegisterDescriptor(target, thread, frame, name, fullName, pos, depth);
330
throw new CDIException(CdiResources.getString("cdi.VariableManager.Unknown_variable_object")); //$NON-NLS-1$
333
String[] castings = varDesc.getCastingTypes();
334
if (castings == null) {
335
castings = new String[] { type };
337
String[] temp = new String[castings.length + 1];
338
System.arraycopy(castings, 0, temp, 0, castings.length);
339
temp[castings.length] = type;
342
vo.setCastingTypes(castings);
346
public Variable createVariable(VariableDescriptor varDesc) throws CDIException {
347
if (varDesc instanceof ArgumentDescriptor) {
348
return createArgument((ArgumentDescriptor)varDesc);
349
} else if (varDesc instanceof LocalVariableDescriptor) {
350
return createLocalVariable((LocalVariableDescriptor)varDesc);
351
} else if (varDesc instanceof GlobalVariableDescriptor) {
352
return createGlobalVariable((GlobalVariableDescriptor)varDesc);
353
} else if (varDesc instanceof RegisterDescriptor) {
354
RegisterManager regMgr = ((Session)getSession()).getRegisterManager();
355
return regMgr.createRegister((RegisterDescriptor)varDesc);
356
} else if (varDesc instanceof ThreadStorageDescriptor) {
357
return createThreadStorage((ThreadStorageDescriptor)varDesc);
359
throw new CDIException(CdiResources.getString("cdi.VariableManager.Unknown_variable_object")); //$NON-NLS-1$
362
public Argument createArgument(ArgumentDescriptor argDesc) throws CDIException {
363
Variable variable = findVariable(argDesc);
364
Argument argument = null;
365
if (variable != null && variable instanceof Argument) {
366
argument = (Argument) variable;
368
if (argument == null) {
369
String name = argDesc.getQualifiedName();
370
StackFrame stack = (StackFrame)argDesc.getStackFrame();
371
Target target = (Target)argDesc.getTarget();
372
Thread currentThread = (Thread)target.getCurrentThread();
373
StackFrame currentFrame = currentThread.getCurrentStackFrame();
374
synchronized(target.getLock()) {
376
target.setCurrentThread(stack.getThread(), false);
377
((Thread)stack.getThread()).setCurrentStackFrame(stack, false);
378
MISession mi = target.getMISession();
379
CommandFactory factory = mi.getCommandFactory();
380
MIVarCreate var = factory.createMIVarCreate(name);
381
mi.postCommand(var, -1);
382
argument = new Argument(argDesc, var);
383
// mi.postCommand(var);
384
// MIVarCreateInfo info = var.getMIVarCreateInfo();
385
// if (info == null) {
386
// throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
388
// argument = new Argument(argDesc, info.getMIVar());
389
List variablesList = getVariablesList(target);
390
variablesList.add(argument);
391
} catch (MIException e) {
392
throw new MI2CDIException(e);
394
target.setCurrentThread(currentThread, false);
395
currentThread.setCurrentStackFrame(currentFrame, false);
402
public ICDIArgumentDescriptor[] getArgumentDescriptors(StackFrame frame) throws CDIException {
403
List argObjects = new ArrayList();
404
Target target = (Target)frame.getTarget();
405
Thread currentThread = (Thread)target.getCurrentThread();
406
StackFrame currentFrame = currentThread.getCurrentStackFrame();
407
synchronized(target.getLock()) {
409
target.setCurrentThread(frame.getThread(), false);
410
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
411
MISession mi = target.getMISession();
412
CommandFactory factory = mi.getCommandFactory();
413
int depth = frame.getThread().getStackFrameCount();
414
int level = frame.getLevel();
415
// Need the GDB/MI view of level which the reverse i.e. Highest frame is 0
416
int miLevel = depth - level;
417
MIStackListArguments listArgs = factory.createMIStackListArguments(false, miLevel, miLevel);
419
mi.postCommand(listArgs);
420
MIStackListArgumentsInfo info = listArgs.getMIStackListArgumentsInfo();
422
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
424
MIFrame[] miFrames = info.getMIFrames();
425
if (miFrames != null && miFrames.length == 1) {
426
args = miFrames[0].getArgs();
429
for (int i = 0; i < args.length; i++) {
430
ArgumentDescriptor arg = new ArgumentDescriptor(target, null, frame, args[i].getName(), null, args.length - i, level);
434
} catch (MIException e) {
435
throw new MI2CDIException(e);
437
target.setCurrentThread(currentThread, false);
438
currentThread.setCurrentStackFrame(currentFrame, false);
441
return (ICDIArgumentDescriptor[]) argObjects.toArray(new ICDIArgumentDescriptor[0]);
444
public GlobalVariableDescriptor getGlobalVariableDescriptor(Target target, String filename, String function, String name) throws CDIException {
445
if (filename == null) {
446
filename = new String();
448
if (function == null) {
449
function = new String();
454
StringBuffer buffer = new StringBuffer();
455
if (filename.length() > 0) {
456
buffer.append('\'').append(filename).append('\'').append("::"); //$NON-NLS-1$
458
if (function.length() > 0) {
459
buffer.append(function).append("::"); //$NON-NLS-1$
462
return new GlobalVariableDescriptor(target, null, null, buffer.toString(), null, 0, 0);
465
public GlobalVariable createGlobalVariable(GlobalVariableDescriptor varDesc) throws CDIException {
466
Variable variable = findVariable(varDesc);
467
GlobalVariable global = null;
468
if (variable instanceof GlobalVariable) {
469
global = (GlobalVariable)variable;
471
if (global == null) {
472
String name = varDesc.getQualifiedName();
473
Target target = (Target)varDesc.getTarget();
475
MISession mi = target.getMISession();
476
CommandFactory factory = mi.getCommandFactory();
477
MIVarCreate var = factory.createMIVarCreate(name);
478
mi.postCommand(var, -1);
479
global = new GlobalVariable(varDesc, var);
480
// mi.postCommand(var;
481
// MIVarCreateInfo info = var.getMIVarCreateInfo();
482
// if (info == null) {
483
// throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
485
// global = new GlobalVariable(varDesc, info.getMIVar());
486
List variablesList = getVariablesList(target);
487
variablesList.add(global);
488
} catch (MIException e) {
489
throw new MI2CDIException(e);
495
public ICDILocalVariableDescriptor[] getLocalVariableDescriptors(StackFrame frame) throws CDIException {
496
List varObjects = new ArrayList();
497
Target target = (Target)frame.getTarget();
498
Thread currentThread = (Thread)target.getCurrentThread();
499
StackFrame currentFrame = currentThread.getCurrentStackFrame();
500
synchronized(target.getLock()) {
502
target.setCurrentThread(frame.getThread(), false);
503
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
504
MISession mi = target.getMISession();
505
CommandFactory factory = mi.getCommandFactory();
506
int level = frame.getLevel();
508
MIStackListLocals locals = factory.createMIStackListLocals(false);
509
mi.postCommand(locals);
510
MIStackListLocalsInfo info = locals.getMIStackListLocalsInfo();
512
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
514
args = info.getLocals();
516
for (int i = 0; i < args.length; i++) {
517
LocalVariableDescriptor varObj = new LocalVariableDescriptor(target, null, frame, args[i].getName(), null, args.length - i, level);
518
varObjects.add(varObj);
521
} catch (MIException e) {
522
throw new MI2CDIException(e);
524
target.setCurrentThread(currentThread, false);
525
currentThread.setCurrentStackFrame(currentFrame, false);
528
return (ICDILocalVariableDescriptor[]) varObjects.toArray(new ICDILocalVariableDescriptor[0]);
531
public LocalVariable createLocalVariable(LocalVariableDescriptor varDesc) throws CDIException {
532
Variable variable = findVariable(varDesc);
533
LocalVariable local = null;
534
if (variable instanceof LocalVariable) {
535
local = (LocalVariable)variable;
538
String name = varDesc.getQualifiedName();
539
StackFrame stack = (StackFrame)varDesc.getStackFrame();
540
Target target = (Target)varDesc.getTarget();
541
Thread currentThread = (Thread)target.getCurrentThread();
542
StackFrame currentFrame = currentThread.getCurrentStackFrame();
543
synchronized(target.getLock()) {
545
target.setCurrentThread(stack.getThread(), false);
546
((Thread)stack.getThread()).setCurrentStackFrame(stack, false);
547
MISession mi = target.getMISession();
548
CommandFactory factory = mi.getCommandFactory();
549
MIVarCreate var = factory.createMIVarCreate(name);
550
mi.postCommand(var, -1);
551
local = new LocalVariable(varDesc, var);
552
// mi.postCommand(var);
553
// MIVarCreateInfo info = var.getMIVarCreateInfo();
554
// if (info == null) {
555
// throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
557
// local = new LocalVariable(varDesc, info.getMIVar());
558
List variablesList = getVariablesList(target);
559
variablesList.add(local);
560
} catch (MIException e) {
561
throw new MI2CDIException(e);
563
target.setCurrentThread(currentThread, false);
564
currentThread.setCurrentStackFrame(currentFrame, false);
571
public ICDIThreadStorageDescriptor[] getThreadStorageDescriptors(Thread thread) throws CDIException {
572
return new ICDIThreadStorageDescriptor[0];
575
public ThreadStorage createThreadStorage(ThreadStorageDescriptor desc) throws CDIException {
576
throw new CDIException(CdiResources.getString("cdi.VariableManager.Unknown_variable_object")); //$NON-NLS-1$
579
public void destroyVariable(Variable variable) throws CDIException {
580
// Fire a destroyEvent ?
581
Target target = (Target)variable.getTarget();
582
MISession mi = target.getMISession();
583
// no need to call -var-delete for variable that are not in
584
// the list most probaby they are children of other variables and in this case
585
// we should not delete them
586
List varList = getVariablesList(target);
587
if (varList.contains(variable)) {
588
removeMIVar(mi, variable.getMIVar());
590
MIVarDeletedEvent del = new MIVarDeletedEvent(mi, variable.getMIVar().getVarName());
594
public void destroyAllVariables(Target target) throws CDIException {
595
Variable[] variables = getVariables(target);
596
MISession mi = target.getMISession();
597
for (int i = 0; i < variables.length; ++i) {
598
removeMIVar(mi, variables[i].getMIVar());
599
MIVarDeletedEvent del = new MIVarDeletedEvent(mi, variables[i].getMIVar().getVarName());
605
* Update the elements in the cache, from the response of the "-var-update"
606
* mi/command. Althought tempting we do not use the "-var-update *" command, since
607
* for some reason on gdb-5.2.1 it starts to misbehave until it hangs ... sigh
608
* We take the approach of updating the variables ourselfs. But we do it a smart
609
* way by only updating the variables visible in the current stackframe but not
610
* the other locals in different frames. The downside if any side effects we loose,
611
* This ok, since the IDE only a frame at a time.
614
public void update(Target target) throws CDIException {
617
List eventList = new ArrayList();
618
MISession mi = target.getMISession();
619
CommandFactory factory = mi.getCommandFactory();
620
Variable[] vars = getVariables(target);
621
ICDIStackFrame[] frames = null;
622
StackFrame currentStack = null;
623
Thread currentThread = (Thread)target.getCurrentThread();
624
if (currentThread != null) {
625
currentStack = currentThread.getCurrentStackFrame();
626
if (currentStack != null) {
627
highLevel = currentStack.getLevel();
629
if (highLevel > MAX_STACK_DEPTH) {
630
highLevel = MAX_STACK_DEPTH;
632
lowLevel = highLevel - MAX_STACK_DEPTH;
636
frames = currentThread.getStackFrames(0, highLevel);
638
for (int i = 0; i < vars.length; i++) {
639
Variable variable = vars[i];
640
if (isVariableNeedsToBeUpdate(variable, currentStack, frames, lowLevel)) {
641
update(target, variable, eventList);
643
variable.setUpdated(false);
646
MIEvent[] events = (MIEvent[]) eventList.toArray(new MIEvent[0]);
647
mi.fireEvents(events);
650
public void update(Variable variable) throws CDIException {
651
Target target = (Target)variable.getTarget();
652
MISession mi = target.getMISession();
653
List eventList = new ArrayList();
654
update(target, variable, eventList);
655
MIEvent[] events = (MIEvent[]) eventList.toArray(new MIEvent[0]);
656
mi.fireEvents(events);
659
public void update(Target target, Variable variable, List eventList) throws CDIException {
660
MISession mi = target.getMISession();
661
CommandFactory factory = mi.getCommandFactory();
662
MIVarChange[] changes = noChanges;
664
String miVarName = variable.getMIVar().getVarName();
665
MIVarUpdate update = factory.createMIVarUpdate(miVarName);
667
mi.postCommand(update);
668
MIVarUpdateInfo info = update.getMIVarUpdateInfo();
670
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
672
changes = info.getMIVarChanges();
673
} catch (MIException e) {
674
//throw new MI2CDIException(e);
675
eventList.add(new MIVarDeletedEvent(mi, miVarName));
677
} catch (CDIException exc) {
678
// When the variable was out of scope the fisrt time, the getMIVar() generates an exception.
679
// Then create again the variable, set the fVarCreateCMD of Variable class and try again the update command.
681
MIVarCreate var = factory.createMIVarCreate(variable.getName());
683
MIVarCreateInfo info = var.getMIVarCreateInfo();
685
throw new CDIException(CdiResources.getString("cdi.Common.No_answer")); //$NON-NLS-1$
687
variable.setMIVarCreate(var);
688
update(target, variable, eventList);
689
} catch (MIException e) {
690
// Creating failed, variable not in scope => remove
691
// No events to fire as the variable isn't backed by a MIVar
692
getVariablesList(target).remove(variable);
693
variable.setUpdated(false);
695
} catch (CDIException e) {
699
variable.setUpdated(true);
700
for (int j = 0; j < changes.length; j++) {
701
String n = changes[j].getVarName();
702
if (changes[j].isInScope()) {
703
eventList.add(new MIVarChangedEvent(mi, n));
705
destroyVariable(variable);
706
eventList.add(new MIVarDeletedEvent(mi, n));
712
* We are trying to minimize the impact of the updates, this can be very long and unncessary if we
713
* have a very deep stack and lots of local variables. We can assume here that the local variables
714
* in the other non-selected stackframe will not change and only update the selected frame variables.
721
boolean isVariableNeedsToBeUpdate(Variable variable, ICDIStackFrame current, ICDIStackFrame[] frames, int lowLevel)
722
throws CDIException {
723
ICDIStackFrame varStack = variable.getStackFrame();
724
boolean inScope = false;
726
// Something wrong and the program terminated bail out here.
727
if (current == null || frames == null) {
731
// If the variable Stack is null, it means this is a global variable we should update
732
if (varStack == null) {
734
} else if (varStack.equals(current)) {
735
// The variable is in the current selected frame it should be updated
738
if (varStack.getLevel() >= lowLevel) {
739
// Check if the Variable is still in Scope
740
// if it is no longer in scope so update() can call "-var-delete".
741
for (int i = 0; i < frames.length; i++) {
742
if (varStack.equals(frames[i])) {
750
// return true if the variable is no longer in scope we
751
// need to call -var-delete.