2002-10-30 20:52:05 +00:00
|
|
|
2002-10-30 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/cdi/MemoryBlock.java (setValue): reuse refresh()
|
|
|
|
to update the memory and fire any MemoryChangedEvents.
|
|
|
|
|
2002-10-28 20:38:27 +00:00
|
|
|
2002-10-26 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/cdi/MemoryBlock.java (setValue): Generate
|
|
|
|
a MemoryChangeEvent when the value is set, gdb/mi will not
|
|
|
|
do it.
|
|
|
|
|
2002-10-26 23:40:44 +00:00
|
|
|
2002-10-25 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/cdi/CThread.java (getStackFrames): Save the
|
|
|
|
current thread before changing and restore when operation finish.
|
|
|
|
|
|
|
|
* src/.../core/cdi/MemoryBlock.java (refresh): Flush the old
|
|
|
|
data and get new memory.
|
|
|
|
(update): New method to compare individual blocks.
|
|
|
|
|
2002-10-26 20:29:21 +00:00
|
|
|
2002-10-25 Alain Magloire
|
|
|
|
|
|
|
|
Automatically suspend/resume gdb when setting a breakpoint.
|
|
|
|
The workflow when debuggin which gdb command prompt is to
|
|
|
|
hit CTRL-C set the breakpoint and continue. The UI debugger
|
|
|
|
should be smart enought to do this by itself. So if the
|
|
|
|
inferior is running, when setting a breakpoint the program
|
|
|
|
is suspended(target.suspend()), the suspend event is ignore
|
|
|
|
the breakpoint is set (--break-insert) and the target is resume.
|
|
|
|
To ignore a specific event, we use a (mis)behaviour of gdb that
|
|
|
|
associate the suspend(*stopped) with the last execution command.
|
|
|
|
(gdb)
|
|
|
|
111-exec-continue
|
|
|
|
111^running
|
|
|
|
(gdb)
|
|
|
|
222-exec-interrupt
|
|
|
|
222^done
|
|
|
|
(gdb)
|
|
|
|
111*stopped,signal-name="SIGINT",signal-meaning="Interrupt",
|
|
|
|
frame={addr="0x00010140",func="foo",args=[],file="try.c",line="13"}
|
|
|
|
(gdb)
|
|
|
|
In the case above event 111 is ignore.
|
|
|
|
|
|
|
|
* src/.../core/command/CLICommand.java (toString): Always put
|
|
|
|
the identifying token.
|
|
|
|
* src/.../core/command/Command.java (setToken): Removed.
|
|
|
|
(getUniqToken): New method returns a global uniq token.
|
|
|
|
(getToken): Returns a uniq token for the command.
|
|
|
|
* src/.../core/MIInferior.java (setTerminated): New argument token,
|
|
|
|
since now all MIEvent has the corresponding command token.
|
|
|
|
* src/.../core/MISession.java (cmdCount): Removed.
|
|
|
|
(postCommand): the command getToken() will return a uniq token.
|
|
|
|
* src/.../core/RxThread.java (processMIOOBRecord): MIEvent take
|
|
|
|
the corresponding command token as argument.
|
|
|
|
* src/.../core/TxThrea.java (token): Field removed, token are no
|
|
|
|
longer created in this tread.
|
|
|
|
* src/.../core/event/MIBreakpointEvent.java:
|
|
|
|
* src/.../core/event/MIBreakpointEvent.java:
|
|
|
|
* src/.../core/event/MIChangedEvent.java:
|
|
|
|
* src/.../core/event/MIDetachedEvent.java:
|
|
|
|
* src/.../core/event/MIEvent.java:
|
|
|
|
* src/.../core/event/MIFunctionFinishedEvent.java:
|
|
|
|
* src/.../core/event/MIGDBExitEvent.java:
|
|
|
|
* src/.../core/event/MIInferiorExitEvent.java:
|
|
|
|
* src/.../core/event/MILocationReachedEvent.java:
|
|
|
|
* src/.../core/event/MIMemoryChangedEvent.java:
|
|
|
|
* src/.../core/event/MIRegisterChangedEvent.java:
|
|
|
|
* src/.../core/event/MIRunningEvent.java:
|
|
|
|
* src/.../core/event/MISignalEvent.java:
|
|
|
|
* src/.../core/event/MISteppingRangeEvent.java:
|
|
|
|
* src/.../core/event/MIStoppedEvent.java:
|
|
|
|
* src/.../core/event/MIThreadExitEvent.java:
|
|
|
|
* src/.../core/event/MIVarChangedEvent.java:
|
|
|
|
* src/.../core/event/MIWatchpointScopeEvent.java:
|
|
|
|
* src/.../core/event/MIWatchpointTriggerEvent.java:
|
|
|
|
Calls super with getToken().
|
|
|
|
* src/.../core/cdi/BreakpointManager.java (allowProgramInterruption):
|
|
|
|
New method to allow suspending the program to set a breakpoint.
|
|
|
|
(suspendInferior): get the last token execution an ignore the suspend
|
|
|
|
event.
|
|
|
|
* src/.../core/cdi/CTarget.java (getLastExecutionToken): New method
|
|
|
|
returns the token of the last execution command.
|
|
|
|
* src/.../core/cdi/EventManager.java (enableEventToken): New method.
|
|
|
|
(enableEventTokens): New method.
|
|
|
|
(disableEventToken): New method.
|
|
|
|
(disableEventTokens): New method.
|
|
|
|
(update): Ignore token in the disable list.
|
|
|
|
* src/.../core/cdi/RegisterManager.java (update): MIEvent takes
|
|
|
|
a token.
|
|
|
|
* src/.../core/cdi/Variable.java (setValue): MIEvent takes a token.
|
|
|
|
* src/.../core/cdi/VariableManager.java (update): MIEvent takes a token.
|
|
|
|
|
2002-10-24 15:06:53 +00:00
|
|
|
2002-10-24 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/RxThread.java (processMIOutput): Fire a
|
|
|
|
suspended event when seeing an error.
|
|
|
|
|
2002-10-24 13:44:11 +00:00
|
|
|
2002-10-24 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/output/MIConst.java (isoC): Change to return
|
|
|
|
a string instead '\n' is platform dependent and has to be
|
|
|
|
translate to "\r\n" for SWT widgets to work correctly on windows.
|
|
|
|
|
2002-10-24 02:43:27 +00:00
|
|
|
2002-10-23 Alain Magloire
|
|
|
|
|
|
|
|
gdb/mi for program control command will fire a change state event:
|
|
|
|
-exec-run
|
|
|
|
^running
|
|
|
|
This allow the UI to change its state and wait for the suspended.
|
|
|
|
Providing a gdb prompt adds some problems, since there is no state
|
|
|
|
change, i.e.(^running) after command like, next/step/...:
|
|
|
|
next
|
|
|
|
&"next\n"
|
|
|
|
...
|
|
|
|
So to palliate, the txthread do some query when the commands are
|
|
|
|
CLI commands trying to discover the type and fire any appropriate
|
|
|
|
events on behalf on gdb.
|
|
|
|
|
|
|
|
* src/.../core/RxThread.java (createEvent): Adjust the parser to
|
|
|
|
not rely on the oob "*stopped", since for CLI command it is not
|
|
|
|
in the result-class. So the suspended state will be base of
|
|
|
|
the "reason" only.
|
|
|
|
* src/.../core/TxThread.java (processCLICommand): new method,
|
|
|
|
get the command and try to recognize if it is a program control
|
|
|
|
command like: next, step, etc ..
|
|
|
|
* src/.../core/command/CLICommand.java (getOperation): New method,
|
|
|
|
returns the command string.
|
|
|
|
|
2002-10-22 20:29:02 +00:00
|
|
|
2002-10-22 Alain Magloire
|
|
|
|
|
2002-10-24 02:43:27 +00:00
|
|
|
Change the framework to support access to gdb prompt.
|
2002-10-22 20:29:02 +00:00
|
|
|
Trying to reuse as much as possible Eclipse framework.
|
|
|
|
The session/gdb process is available via CDI.
|
|
|
|
|
|
|
|
* src/.../core/GDBStreamsProxy.java: Removed.
|
|
|
|
* src/.../core/GDBProcess.java: Removed.
|
|
|
|
* src/.../core/GDBStreamMonitor.java: Removed.
|
|
|
|
* src/.../core/SessionProcess.java: New file.
|
|
|
|
* src/.../core/MISession.java (getMISessionProcess):
|
|
|
|
New method, returns a "fake" Process that wraps the input/outpu
|
|
|
|
stream of gdb.
|
|
|
|
(getGDBProcess): was getMIProcess(), renamed.
|
|
|
|
* src/.../core/cdi/CSession.java (getSessionProcess): New method
|
|
|
|
return gdb process.
|
|
|
|
|
2002-10-22 15:54:25 +00:00
|
|
|
2002-10-22 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/GDBStreamsProxy.java (write):
|
|
|
|
Replace the OutputStream with a Write class.
|
|
|
|
And clear the buffer on flush().
|
|
|
|
|
2002-10-22 04:53:30 +00:00
|
|
|
2002-10-21 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/GDBProcess.java (getExitValue): Catch
|
|
|
|
IllegalThreadStateException.
|
|
|
|
(getAttribute): Only create Properties, when call.
|
|
|
|
(setAttribute): Only create Properties, when call.
|
|
|
|
(getAdapter): Implemented.
|
|
|
|
(canTerminate): true only of the process is alive.
|
|
|
|
(GDBProcess): Takes one more argument the name.
|
|
|
|
* src/.../core/GDBStreamMonitor.java (fireStreamAppend): New method.
|
|
|
|
Use a synchronized LinkedList for the listeners.
|
|
|
|
(read): new Method.
|
|
|
|
(startMonitoring): New method, start a thread in the background
|
|
|
|
to monitor the input.
|
|
|
|
* src/.../core/GDBStreamsProxy.java (getErrorStream): Start the monitor thread.
|
|
|
|
(getOutputStream): Start the monitor thread.
|
|
|
|
|
2002-10-21 21:38:52 +00:00
|
|
|
2002-10-21 Alain Magloire
|
|
|
|
|
|
|
|
Framework for having a gdb console. The idea is to reuse
|
|
|
|
the eclipse console and save a lot of work. We "adapt"
|
|
|
|
the gdb Process to what eclipse debug LaunchView wants(IProcess).
|
|
|
|
So when this fake "gdb process" is selected we can grab the
|
|
|
|
input/output of the console and redirect everything to raw gdb.
|
|
|
|
|
|
|
|
* src/.../core/GDBProcess.java: New file, it implements Eclipse
|
|
|
|
debug class IProcess.
|
|
|
|
* src/.../core/GDBStreamMonitor: New file, it implements Eclipse
|
|
|
|
debug class IStreamMonitor.
|
|
|
|
* src/.../core/GDBStreamsProxy: New file, it implements Eclipse
|
|
|
|
debug class IStreamsProxy.
|
|
|
|
* src/../core/MISession.java (getMIConsoleStream): New method
|
|
|
|
to return the mi console stream output that we get from gdb/mi.
|
|
|
|
(getMILogStream): New method, to return the mi log stream output
|
|
|
|
that we get from gdb/mi.
|
|
|
|
(terminate): close the fake MI Console and Log streams.
|
|
|
|
* src/../core/RxThread.java (processMIOOBRecord): Redirect the
|
|
|
|
console and the log stream to a buffer pipe.
|
|
|
|
|
2002-10-21 20:38:32 +00:00
|
|
|
2002-10-21 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/cdi/EventManager.java (update): Only
|
|
|
|
fire the event for MemoryChangedEvent if the block was
|
|
|
|
not frozen.
|
|
|
|
|
2002-10-21 02:56:04 +00:00
|
|
|
2002-10-20 Alain Magloire
|
|
|
|
|
|
|
|
Eclipse provides plugins a way to trace by having an .options file,
|
|
|
|
this mechanism is use to print out the mi exchange between gdb
|
|
|
|
and the plugin. To enable this in the debug launch one must enable
|
|
|
|
"tracing" and set for the "org.eclipse.debug.mi.core/debug" to true.
|
|
|
|
But one problem, the console will simply blow taking down eclipse,
|
|
|
|
for big MI line response, say 4k length, for example asking the children
|
|
|
|
of "char buffer[4096]", -var-list-children varxx.
|
|
|
|
This seem only to happen in Eclipse-gtk or Eclipse-motif
|
|
|
|
on GNU/Linux, so it will be break in smaller chunks to give a chance to
|
|
|
|
the console.
|
|
|
|
|
|
|
|
* .options: Set debug to true.
|
|
|
|
* src/.../core/MIPlugin.java (debugLog): Break the log line in small chuncks of 100.
|
2002-10-21 20:38:32 +00:00
|
|
|
* src/.../core/MISession.java (postCommand): Print the gdb/mi command.
|
|
|
|
* src/.../core/RxThread.java (run): Print gdb/mi responses.
|
2002-10-21 02:56:04 +00:00
|
|
|
|
2002-10-20 23:30:22 +00:00
|
|
|
2002-10-20 Alain Magloire
|
|
|
|
|
|
|
|
-data-write-register-values is not in the texinfo manual but implemented in
|
|
|
|
gdb-5.2.1/gdb/mi/mim-main.c:
|
|
|
|
Write given values into registers. The registers and values are
|
|
|
|
given as pairs. The corresponding MI command is
|
|
|
|
-data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]
|
|
|
|
|
|
|
|
* src/.../core/command/MIDataWriteRegisterValues.java: New file.
|
|
|
|
* src/.../core/command/CommandFactory.java (createMIDataWriteMemory): New method.
|
|
|
|
* src/.../core/cdi/Register.java (setValue): Implemented.
|
|
|
|
|
|
|
|
2002-10-20 Alain Magloire
|
|
|
|
|
|
|
|
Althought -data-write-memory is not documented in the texinfo manual
|
|
|
|
it is implemented and well documented in the code(gdb-5.2.1/gdb/mi/mi-main.c).
|
|
|
|
"mi_cmd_data_write_memory: Usage: [-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE.");
|
|
|
|
|
|
|
|
* src/.../core/command/MIDataWriteMemory.java: New file
|
|
|
|
* src/.../core/command/CommandFactory.java (createMIDataWriteMemory): New method.
|
|
|
|
* src/.../core/cdi/MemoryBlock.java (setValue): Implemented.
|
|
|
|
|
|
|
|
2002-10-20 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../core/cdi/CTarget.java (getMemoryBlock): Remove
|
|
|
|
we use the MemoryManager instead.
|
|
|
|
(EvaluateExpressionToValue): Removed not use.
|
|
|
|
* src/.../core/cdi/SourceManager.java (setFile): Removed not use.
|
|
|
|
(getFile): Removed not use.
|
|
|
|
(reset): Removed not use.
|
|
|
|
|
2002-10-19 19:21:24 +00:00
|
|
|
2002-10-19 Alain Magloire
|
|
|
|
|
|
|
|
The responsability to generate Events for modify memory blocks is push
|
|
|
|
on the CDI implementation. The way we do this is every time consuming,
|
|
|
|
when the inferior is suspended(see EventManager.processSuspendedEvent()),
|
|
|
|
MemoryManager.update() is called, the method will go through the list of MemoryBlocks
|
|
|
|
that are not MemoryBlocks.setFrozen() and fetch the new memories, the data is compare
|
|
|
|
and MemoryChangedEvents are fired for blocks with changed values.
|
|
|
|
Gdb/mi var objects does not seem to provide any support for Memory ranges.
|
|
|
|
|
|
|
|
* src/.../core/cdi/MemoryChangedEvent.java: New File implements ICDIMemoryChangedEvent.
|
|
|
|
* src/.../core/cdi/EventManager.java (update): Process MIMemoryChangedEvent's.
|
|
|
|
(processSuspendedEvent): call MemoryManager.update().
|
|
|
|
* src/.../core/cdi/MemoryBlock.java (getExpression): New method.
|
|
|
|
(getMIDataReadMemoryInfo): New method.
|
|
|
|
(setMIDataReadMemoryInfo): New method.
|
|
|
|
* src/.../core/cdi/MemoryManager.java (update): New method.
|
|
|
|
(compareBlock): New method.
|
|
|
|
(listMemoryBlocks): New method.
|
|
|
|
|
|
|
|
* src/.../core/cdi/CTarget.java (setCurrentThread): Catch null pointer.
|
|
|
|
(getCThreads): Likewise.
|
|
|
|
* src/.../core/event/MIMemoryChangedEvent.java: New File.
|
|
|
|
* src/.../core/event/MIThreadExitEvent.java: Indentation fixes.
|
|
|
|
* src/.../core/event/MIVarChangedEvent.java: Indentation fixes.
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-10-17 14:30:00 +00:00
|
|
|
2002-10-16 Alain Magloire
|
|
|
|
|
|
|
|
* src/.../mi/core/cdi/MemoryManager.java (createMemoryBlock):
|
|
|
|
New method that takes a string instead of a long, rearrange
|
|
|
|
the method for it.
|
|
|
|
|
2002-10-13 02:33:31 +00:00
|
|
|
2002-10-12 Alain Magloire
|
|
|
|
|
|
|
|
There are some serious problems with gdb/mi, for example
|
|
|
|
the most recurrent one is when using -data-disassemble
|
|
|
|
in a threaded program, GNU/Linux uses a thread manager
|
|
|
|
when trying to access the stackframe, gdb usually coredumps
|
|
|
|
with an assert, it goes something like this:
|
2002-10-13 02:35:02 +00:00
|
|
|
|
|
|
|
-data-disassemble -f manager.c -l 136 -n 100 0
|
2002-10-13 02:33:31 +00:00
|
|
|
&"Cannot access memory at address 0x4002d794\n"
|
|
|
|
^error,msg="Cannot access memory at address 0x4002d794"
|
|
|
|
(gdb)
|
|
|
|
-data-disassemble -s 0x4002d900 -e 0x4002d964 0
|
|
|
|
&"Cannot access memory at address 0x4002d900\n"
|
|
|
|
^error,msg="Cannot access memory at address 0x4002d900"
|
|
|
|
(gdb)
|
|
|
|
-thread-select 2
|
|
|
|
&"ui-out.c:133: gdb-internal-error: push_level: Assertion `uiout->level >= 0 && uiout->level < MAX_UI_OUT_LEVELS' failed.\n"
|
|
|
|
|
|
|
|
The RxThread will spawn a thread to terminate the session
|
|
|
|
and clear the receiving queue.
|
|
|
|
|
|
|
|
|
|
|
|
* RxThread.java (run): When the thread is being cancel() or
|
|
|
|
running out of run(), clear the receiving queue(rxQueue) and
|
|
|
|
notify any commands waiting.
|
|
|
|
|
|
|
|
* TxTread.java (run): Before putting the command in the
|
|
|
|
receiving queue(rxQueue) check to see if the thread is
|
|
|
|
still running.
|
|
|
|
When the thread is being cancel() or running out of run(),
|
|
|
|
clear the transmition queue(txQueue) an notify any commands
|
|
|
|
waiting.
|
|
|
|
|
|
|
|
* Queue.java (clearItems): New method that clear the items
|
|
|
|
on the queue and returning them.
|
|
|
|
|
|
|
|
* CommandQueue.java (clearCommands): New method calls super.clearItems()
|
|
|
|
whith the appropriate castings.
|
|
|
|
|
|
|
|
* cdi/CThread.java (setCurrentStackFrame): Check for null.
|
|
|
|
|
2002-10-13 01:59:14 +00:00
|
|
|
2002-10-12 Alain Magloire
|
|
|
|
|
|
|
|
The memory block is implemented with
|
|
|
|
-data-read-memory (MIDataReadMemory)
|
|
|
|
Since the ICDIMemoryBlock only have
|
|
|
|
byte[] getBytes()
|
|
|
|
We will always issue:
|
|
|
|
-data-read-memory address x 1 1 length
|
|
|
|
The CDI upper layer will deal with any conversions
|
|
|
|
|
|
|
|
The problem now is how to send changedEvent when
|
|
|
|
an element of the memory changed.
|
|
|
|
|
|
|
|
* cdi/MemoryBlock.java (getLength): Implemented
|
|
|
|
(getBytes): Implemented
|
|
|
|
(getStartAddress): Implemented
|
|
|
|
|
|
|
|
* cdi/MemoryManager.java: Implemented.
|
|
|
|
|
|
|
|
* command/MIDataReadMemory (getMIDataReadMemoryInfo):
|
|
|
|
New helper method.
|
|
|
|
|
2002-10-12 23:51:24 +00:00
|
|
|
2002-10-12 Alain Magloire
|
|
|
|
|
|
|
|
* cdi/Location (getInstructions): Methods removed
|
|
|
|
no longer define in ICDILocation.
|
|
|
|
|
2002-10-11 14:41:35 +00:00
|
|
|
2002-10-11 Alain Magloire
|
|
|
|
|
2002-10-12 01:22:05 +00:00
|
|
|
* cdi/SourceManager (getMixedInstruction):
|
|
|
|
Implement the 3 new methods to return Mixed source
|
|
|
|
and assemby instructions.
|
|
|
|
|
|
|
|
* cdi/MixedInstruction: New class implements
|
|
|
|
ICDIMixedInstruction.
|
|
|
|
|
|
|
|
2002-10-11 Alain Magloire
|
|
|
|
|
|
|
|
* cdi/ExpressionManager.java: Not needed, removed.
|
2002-10-11 14:41:35 +00:00
|
|
|
|
2002-10-10 22:06:17 +00:00
|
|
|
2002-10-10 Alain Magloire
|
|
|
|
|
|
|
|
The Eclipse/UI/Debug framewok is being very repetive
|
|
|
|
and each command can be ask 2, 3 times. So we'll try
|
|
|
|
to make certain commands smarter by not reissuing them
|
|
|
|
to gdb if the state is the same. We do this when
|
|
|
|
selecting the thread and when selecting the stackframe.
|
|
|
|
|
|
|
|
The other problem is that Eclipse/UI/Debug is calling
|
|
|
|
ICDISession.terminate() twice, this is catch by looking
|
|
|
|
at isTerminated().
|
|
|
|
|
|
|
|
* cdi/CThread.java (setCurrentStackFrame): Make it smarter
|
|
|
|
to not reselect the stack level if it is already at that
|
|
|
|
level.
|
|
|
|
|
|
|
|
* MISession.java (isTerminated): Declare a flag that will
|
|
|
|
hold the state.
|
|
|
|
(terminate): Check if it was call already.
|
|
|
|
|
2002-10-10 15:18:23 +00:00
|
|
|
2002-10-10 Alain Magloire
|
|
|
|
|
2002-10-13 02:33:31 +00:00
|
|
|
* SourceManager.java: Implement getInstructions().
|