--- a/GDBDebugger.st Fri Feb 27 16:47:55 2015 +0100
+++ b/GDBDebugger.st Sat Feb 28 08:34:19 2015 +0100
@@ -33,6 +33,17 @@
"Created: / 02-06-2014 / 23:06:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
+executable: aStringOrFilename
+ "Sets the executable to debug.
+ API equivalent to CLI command:
+
+ (gdb) exec-file <aStringOrFilename>
+ "
+ self send: (GDBMI_file_exec_and_symbols arguments: { aStringOrFilename asString }) wait: false.
+
+ "Created: / 28-02-2015 / 00:19:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
inferiorForId: id
^ inferiors ? #() detect:[:e | e id = id ] ifNone:[
self error: ('No inferior (thread group) with id ''%1'' found!!' bindWith: id)
@@ -107,25 +118,35 @@
!GDBDebugger methodsFor:'commands'!
-send: aGDBCommand
- ^ self send: aGDBCommand wait: true.
+send: command
+ "Execute given `command` and wait until it finishes.
+ Command can be either an instance of GDBCommand or
+ a String. If String, it is assumed to be a CLI command
+ string.
+ "
+ ^ self send: command wait: true.
"Created: / 03-06-2014 / 00:10:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 28-02-2015 / 00:40:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
-send: aGDBCommand wait: aBoolean
- "Sends given command to GDB. If `aBoolean` is true, wait for
+send: command wait: wait
+ "Sends given `command` to GDB. If `aBoolean` is true, wait for
command to finish. Otherwise, return immediately."
- | token blocker handler1 handler2 result |
+ | cmd token blocker handler1 handler2 result |
- (aBoolean and:[Processor activeProcess == connection eventDispatchProcess]) ifTrue:[
+ cmd := command.
+ cmd isString ifTrue:[
+ cmd := GDBCLICommand new value: cmd.
+ ].
+ (wait and:[Processor activeProcess == connection eventDispatchProcess]) ifTrue:[
self error: 'Cannot send commands from within event dispatching process. Would deadlock'.
].
token := self nextCommandSequnceNumber.
- aGDBCommand token: token.
- ^ aBoolean ifTrue:[
+ cmd token: token.
+ ^ wait ifTrue:[
handler1 := [ :ev |
ev token == token ifTrue:[
connection eventAnnouncer unsubscribe: handler1.
@@ -138,16 +159,16 @@
].
blocker := Semaphore new.
connection eventAnnouncer when: GDBCommandResultEvent do: handler1.
- connection pushEvent: (GDBCommandEvent new command: aGDBCommand).
+ connection pushEvent: (GDBCommandEvent new command: cmd).
blocker wait.
result.
] ifFalse:[
- connection pushEvent: (GDBCommandEvent new command: aGDBCommand).
+ connection pushEvent: (GDBCommandEvent new command: cmd).
nil.
]
"Created: / 02-06-2014 / 23:45:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 24-09-2014 / 09:25:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 28-02-2015 / 00:42:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger methodsFor:'event handling'!
--- a/GDBFrame.st Fri Feb 27 16:47:55 2015 +0100
+++ b/GDBFrame.st Sat Feb 28 08:34:19 2015 +0100
@@ -65,15 +65,16 @@
variables := GDBTransientDataHolder debugger: debugger factory:[
| result |
- result := debugger send: (GDBMI_stack_list_variables new arguments: { '--thread' . thread id . '--frame' . level . '--no-values' }).
+ result := debugger send: (GDBMI_stack_list_variables new arguments: { '--thread' . thread id . '--frame' . level . '--simple-values' }).
(result propertyAt: #variables)
- do:[ :each | each debugger: debugger ];
+ do:[ :each | each setFrame: self ];
yourself
].
].
^ variables value
"Created: / 27-02-2015 / 14:56:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 28-02-2015 / 01:04:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBFrame methodsFor:'printing & storing'!
--- a/GDBMI_var_create.st Fri Feb 27 16:47:55 2015 +0100
+++ b/GDBMI_var_create.st Sat Feb 28 08:34:19 2015 +0100
@@ -1,5 +1,7 @@
"{ Package: 'jv:libgdbs' }"
+"{ NameSpace: Smalltalk }"
+
GDBMICommand subclass:#GDBMI_var_create
instanceVariableNames:''
classVariableNames:''
@@ -110,3 +112,11 @@
^ 'var-create'
! !
+!GDBMI_var_create methodsFor:'accessing-descriptors'!
+
+resultDescription
+ ^ GDBVariableObject description
+
+ "Created: / 27-02-2015 / 17:16:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- a/GDBTransientObject.st Fri Feb 27 16:47:55 2015 +0100
+++ b/GDBTransientObject.st Sat Feb 28 08:34:19 2015 +0100
@@ -18,10 +18,12 @@
!GDBTransientObject methodsFor:'initialization'!
debugger: aGDBDebugger
+ self assert: (debugger isNil or:[ debugger == aGDBDebugger ]).
debugger := aGDBDebugger.
stateSequenceNumber := debugger currentInferiorStateSequnceNumber
"Created: / 27-02-2015 / 15:10:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 27-02-2015 / 17:22:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBTransientObject methodsFor:'private'!
--- a/GDBVariable.st Fri Feb 27 16:47:55 2015 +0100
+++ b/GDBVariable.st Sat Feb 28 08:34:19 2015 +0100
@@ -3,7 +3,7 @@
"{ NameSpace: Smalltalk }"
GDBTransientObject subclass:#GDBVariable
- instanceVariableNames:'name'
+ instanceVariableNames:'frame name value'
classVariableNames:''
poolDictionaries:''
category:'GDB-Core'
@@ -24,6 +24,23 @@
name
^ name
+!
+
+value
+ ^ value
+
+ "Created: / 27-02-2015 / 23:37:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBVariable methodsFor:'initialization'!
+
+setFrame: aGDBFrame
+ self assert: frame isNil.
+ self assert: (debugger isNil or:[ debugger == aGDBFrame debugger ]).
+ frame := aGDBFrame.
+ self debugger: frame debugger.
+
+ "Created: / 27-02-2015 / 17:08:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBVariable methodsFor:'printing & storing'!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/GDBDebuggeesResource.st Sat Feb 28 08:34:19 2015 +0100
@@ -0,0 +1,43 @@
+"{ Package: 'jv:libgdbs/tests' }"
+
+"{ NameSpace: Smalltalk }"
+
+TestResource subclass:#GDBDebuggeesResource
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'GDB-Core-Tests'
+!
+
+!GDBDebuggeesResource class methodsFor:'documentation'!
+
+documentation
+"
+ A test resource providing access to various
+ test debuggees.
+
+ [author:]
+ Jan Vrany <jan.vrany@fit.cvut.cz>
+
+ [instance variables:]
+
+ [class variables:]
+
+ [see also:]
+
+"
+! !
+
+!GDBDebuggeesResource methodsFor:'accessing'!
+
+binaryFactorial
+ | binary |
+
+ binary := (Smalltalk getPackageDirectoryForPackage: self class package) / 'c' / 'factorial'.
+ self assert: binary exists.
+ self assert: binary isExecutable.
+ ^ binary pathName
+
+ "Created: / 28-02-2015 / 00:47:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/GDBDebuggerTestCase.st Sat Feb 28 08:34:19 2015 +0100
@@ -0,0 +1,114 @@
+"{ Package: 'jv:libgdbs/tests' }"
+
+"{ NameSpace: Smalltalk }"
+
+TestCase subclass:#GDBDebuggerTestCase
+ instanceVariableNames:'debugger'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'GDB-Core-Tests'
+!
+
+!GDBDebuggerTestCase class methodsFor:'queries'!
+
+isAbstract
+ "Return if this class is an abstract class.
+ True is returned here for myself only; false for subclasses.
+ Abstract subclasses must redefine again."
+
+ ^ self == GDBDebuggerTestCase.
+! !
+
+!GDBDebuggerTestCase methodsFor:'utilities'!
+
+do: block thenWaitFor: announcementClass1
+ ^ self with: debugger do: block thenWaitFor: announcementClass1
+
+ "Created: / 27-02-2015 / 11:44:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+with: debugger do: block thenWaitFor: announcementClass1
+ | announcements |
+
+ announcements := self with: debugger do: block thenWaitForSequence: { announcementClass1 }.
+ announcements notNil ifTrue:[
+ self assert: announcements size == 1.
+ ^ announcements last.
+ ].
+ ^ nil
+
+ "Created: / 01-08-2014 / 12:58:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+with: debugger do: block thenWaitFor: announcementClass1 thenWaitFor: announcementClass2
+ | announcements |
+
+ announcements := self with: debugger do: block thenWaitForSequence: { announcementClass1 . announcementClass2 }.
+ announcements notNil ifTrue:[
+ self assert: announcements size == 2.
+ ^ announcements last.
+ ].
+ ^ nil
+
+ "Created: / 01-08-2014 / 12:58:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+with: debugger do: block thenWaitFor: announcementClass1 thenWaitFor: announcementClass2 thenWaitFor: announcementClass3
+ | announcements |
+
+ announcements := self with: debugger do: block thenWaitForSequence: { announcementClass1 . announcementClass2 . announcementClass3 }.
+ announcements notNil ifTrue:[
+ self assert: announcements size == 3.
+ ^ announcements last.
+ ].
+ ^ nil
+
+ "Created: / 01-08-2014 / 12:59:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+with: debugger do: block thenWaitForSequence: announcementClasses
+ "Blocks the caller until given announcement (or its subclass)
+ is announced until timeout. Returns the annoucement or nil if call
+ timeouted."
+
+ | handlers blocker announcements timeout |
+
+ blocker := Semaphore new.
+
+ handlers := Array new: announcementClasses size.
+ announcements := Array new: announcementClasses size.
+
+ announcementClasses withIndexDo:[ :announcementClass :announcementClassIndex |
+ handlers at: announcementClassIndex put: [ :arg |
+ (announcementClassIndex == 1 or:[ (announcements at: announcementClassIndex - 1) notNil ]) ifTrue:[
+ "Previous announcement arrived, so record announcement and unregister"
+ announcements at: announcementClassIndex put: arg.
+ debugger announcer unsubscribe: (handlers at: announcementClassIndex).
+ handlers at: announcementClassIndex put: nil.
+ announcementClassIndex == handlers size ifTrue:[
+ blocker signal
+ ].
+ ].
+ ].
+ debugger announcer when: announcementClass do: (handlers at: announcementClassIndex).
+ ].
+ block value.
+
+ timeout := DefaultWaitForTimeout.
+ (blocker waitWithTimeoutMs: timeout) isNil ifTrue:[
+ announcements := nil.
+ ].
+
+ handlers do:[:handler | handler notNil ifTrue:[debugger announcer unsubscribe: handler] ].
+ announcements isNil ifTrue:[
+ Logger trace: 'Wait for event(s) timed out'.
+ TimeoutError newException
+ parameter: timeout;
+ raise.
+ ].
+ ^ announcements
+
+ "Created: / 01-08-2014 / 12:57:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 27-02-2015 / 11:43:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- a/tests/GDBDebuggerTests.st Fri Feb 27 16:47:55 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-"{ Package: 'jv:libgdbs/tests' }"
-
-"{ NameSpace: Smalltalk }"
-
-TestCase subclass:#GDBDebuggerTests
- instanceVariableNames:'debugger simulator'
- classVariableNames:'DefaultWaitForTimeout'
- poolDictionaries:''
- category:'GDB-Core-Tests'
-!
-
-!GDBDebuggerTests class methodsFor:'documentation'!
-
-documentation
-"
- documentation to be added.
-
- [author:]
- Jan Vrany <jan.vrany@fit.cvut.cz>
-
- [instance variables:]
-
- [class variables:]
-
- [see also:]
-
-"
-! !
-
-!GDBDebuggerTests class methodsFor:'initialization'!
-
-initialize
- "Invoked at system start or when the class is dynamically loaded."
-
- "/ please change as required (and remove this comment)
-
- DefaultWaitForTimeout := 100.
-
- "Modified: / 27-02-2015 / 11:43:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-! !
-
-!GDBDebuggerTests methodsFor:'running'!
-
-tearDown
- simulator notNil ifTrue:[ simulator stop ].
- debugger notNil ifTrue:[ debugger release ].
-
- "Created: / 06-09-2014 / 02:17:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-! !
-
-!GDBDebuggerTests methodsFor:'tests - basic'!
-
-test_basic_01
- | timeouted |
-
- debugger := GDBDebugger new.
- self assert: debugger isConnected.
- timeouted := ([
- debugger send: (GDBMI_gdb_exit new).
- true.
- ] valueWithTimeout: 3 seconds) isNil.
-
- self assert: timeouted not.
- self assert: debugger isConnected not.
-
- "Created: / 24-06-2014 / 09:06:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified (format): / 06-09-2014 / 02:16:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-test_basic_02
- simulator := GDBSimulatorProcess new record: GDBSimulatorResource session_factorial_01.
- simulator start.
- debugger := GDBDebugger newWithProcess: simulator.
-
- "Created: / 24-06-2014 / 09:09:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 06-09-2014 / 02:18:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-! !
-
-!GDBDebuggerTests methodsFor:'tests - threads'!
-
-test_inferiors_01a
- | tgevent tevent blocker |
-
- blocker := Semaphore new.
- simulator := GDBSimulatorProcess new record: GDBSimulatorResource session_factorial_01.
- simulator start.
- debugger := GDBDebugger newWithProcess: simulator.
- debugger announcer when: GDBThreadGroupEvent do:[:ev |
- tgevent := ev.
- ].
- debugger announcer when: GDBThreadEvent do:[:ev |
- tevent := ev.
- ].
- debugger send: (GDBMI_file_exec_and_symbols new arguments: {'/home/jv/Private/Projects/SmalltalkX/sources/branches/jv1/build/jv/libgdbs/tests/c/factorial'}).
- debugger send: (GDBCLICommand new value: 'b factorial').
-
- self assert: debugger inferiors size == 1.
- self assert: debugger inferiors anElement id = 'i1'.
- "/ No, following won't work as thread-group-added event is
- "/ emited before we register the handler above!!
- "/ self assert: debugger inferiors anElement == event threadGroup.
-
- self
- do:[ debugger send: (GDBCLICommand new value: 'r') ]
- thenWaitFor: GDBStoppedEvent.
-
- self assert: tgevent notNil.
- self assert: tevent notNil.
- self assert: debugger inferiors size == 1.
- self assert: debugger inferiors anElement pid = 7719.
- self assert: debugger inferiors anElement == tgevent threadGroup.
- self assert: debugger inferiors anElement threads size == 1.
- self assert: debugger inferiors anElement threads anElement == tevent thread.
- self assert: debugger inferiors anElement threads anElement isTerminated not.
- self assert: debugger inferiors anElement threads anElement isRunning not.
- self assert: debugger inferiors anElement threads anElement isStopped.
- self assert: debugger inferiors anElement threads anElement stack size == 2.
-
- tgevent := tevent := nil.
-
- debugger send: (GDBCLICommand new value: 'del 1').
- tgevent := self
- do:[ debugger send: (GDBCLICommand new value: 'c') ]
- thenWaitFor: GDBThreadGroupExitedEvent.
-
- self assert: tgevent notNil.
- self assert: debugger inferiors size == 1.
- self assert: debugger inferiors anElement exitCode = 23.
- self assert: debugger inferiors anElement == tgevent threadGroup.
- "/ When thread group exits, all it's threads are dead so
- "/ inferior threads should return an empty collection.
- self assert: debugger inferiors anElement threads isEmptyOrNil.
-
- "Created: / 07-09-2014 / 13:37:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 27-02-2015 / 12:42:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-! !
-
-!GDBDebuggerTests methodsFor:'utilities'!
-
-do: block thenWaitFor: announcementClass1
- ^ self with: debugger do: block thenWaitFor: announcementClass1
-
- "Created: / 27-02-2015 / 11:44:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-with: debugger do: block thenWaitFor: announcementClass1
- | announcements |
-
- announcements := self with: debugger do: block thenWaitForSequence: { announcementClass1 }.
- announcements notNil ifTrue:[
- self assert: announcements size == 1.
- ^ announcements last.
- ].
- ^ nil
-
- "Created: / 01-08-2014 / 12:58:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-with: debugger do: block thenWaitFor: announcementClass1 thenWaitFor: announcementClass2
- | announcements |
-
- announcements := self with: debugger do: block thenWaitForSequence: { announcementClass1 . announcementClass2 }.
- announcements notNil ifTrue:[
- self assert: announcements size == 2.
- ^ announcements last.
- ].
- ^ nil
-
- "Created: / 01-08-2014 / 12:58:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-with: debugger do: block thenWaitFor: announcementClass1 thenWaitFor: announcementClass2 thenWaitFor: announcementClass3
- | announcements |
-
- announcements := self with: debugger do: block thenWaitForSequence: { announcementClass1 . announcementClass2 . announcementClass3 }.
- announcements notNil ifTrue:[
- self assert: announcements size == 3.
- ^ announcements last.
- ].
- ^ nil
-
- "Created: / 01-08-2014 / 12:59:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-with: debugger do: block thenWaitForSequence: announcementClasses
- "Blocks the caller until given announcement (or its subclass)
- is announced until timeout. Returns the annoucement or nil if call
- timeouted."
-
- | handlers blocker announcements timeout |
-
- blocker := Semaphore new.
-
- handlers := Array new: announcementClasses size.
- announcements := Array new: announcementClasses size.
-
- announcementClasses withIndexDo:[ :announcementClass :announcementClassIndex |
- handlers at: announcementClassIndex put: [ :arg |
- (announcementClassIndex == 1 or:[ (announcements at: announcementClassIndex - 1) notNil ]) ifTrue:[
- "Previous announcement arrived, so record announcement and unregister"
- announcements at: announcementClassIndex put: arg.
- debugger announcer unsubscribe: (handlers at: announcementClassIndex).
- handlers at: announcementClassIndex put: nil.
- announcementClassIndex == handlers size ifTrue:[
- blocker signal
- ].
- ].
- ].
- debugger announcer when: announcementClass do: (handlers at: announcementClassIndex).
- ].
- block value.
-
- timeout := DefaultWaitForTimeout.
- (blocker waitWithTimeoutMs: timeout) isNil ifTrue:[
- announcements := nil.
- ].
-
- handlers do:[:handler | handler notNil ifTrue:[debugger announcer unsubscribe: handler] ].
- announcements isNil ifTrue:[
- Logger trace: 'Wait for event(s) timed out'.
- TimeoutError newException
- parameter: timeout;
- raise.
- ].
- ^ announcements
-
- "Created: / 01-08-2014 / 12:57:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 27-02-2015 / 11:43:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-! !
-
-!GDBDebuggerTests class methodsFor:'documentation'!
-
-version_HG
-
- ^ '$Changeset: <not expanded> $'
-! !
-
-
-GDBDebuggerTests initialize!
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/GDBDebuggerTestsR.st Sat Feb 28 08:34:19 2015 +0100
@@ -0,0 +1,92 @@
+"{ Package: 'jv:libgdbs/tests' }"
+
+"{ NameSpace: Smalltalk }"
+
+GDBDebuggerTestCase subclass:#GDBDebuggerTestsR
+ instanceVariableNames:''
+ classVariableNames:''
+ poolDictionaries:''
+ category:'GDB-Core-Tests'
+!
+
+!GDBDebuggerTestsR class methodsFor:'documentation'!
+
+documentation
+"
+ Tests for GDBDebugger (using test programs)
+
+ [author:]
+ Jan Vrany <jan.vrany@fit.cvut.cz>
+
+ [instance variables:]
+
+ [class variables:]
+
+ [see also:]
+
+"
+! !
+
+!GDBDebuggerTestsR class methodsFor:'accessing'!
+
+resources
+ ^ Array with: GDBDebuggeesResource
+
+ "Created: / 28-02-2015 / 00:45:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBDebuggerTestsR methodsFor:'tests - basic'!
+
+test_02
+ | inferior1 thread1 frame1 frame2 |
+
+ debugger := GDBDebugger new.
+ self assert: debugger isConnected.
+
+ debugger executable: GDBDebuggeesResource current binaryFactorial.
+ debugger send: 'b factorial'.
+
+ self
+ do:[ debugger send: 'r' ]
+ thenWaitFor: GDBStoppedEvent.
+
+ self assert: debugger inferiors size == 1.
+ inferior1 := debugger inferiors anElement.
+ self assert: inferior1 threads size == 1.
+ thread1 := inferior1 threads anElement.
+ self assert: thread1 stack size == 2.
+ frame1 := thread1 stack first.
+ frame2 := thread1 stack second.
+ self assert: frame1 variables size == 1.
+ self assert: frame1 variables first name = 'i'.
+
+ self assert: frame2 variables size == 4.
+ self assert: frame2 variables first name = 'argc'.
+ self assert: frame2 variables second name = 'argv'.
+ self assert: frame2 variables third name = 'i'.
+ self assert: frame2 variables fourth name = 'f'.
+
+ self
+ do:[ debugger send: 'd'; send: 'c' ]
+ thenWaitFor: GDBThreadGroupExitedEvent.
+
+ "Created: / 28-02-2015 / 00:55:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_basic_01
+ | timeouted |
+
+ debugger := GDBDebugger new.
+ self assert: debugger isConnected.
+ timeouted := ([
+ debugger send: (GDBMI_gdb_exit new).
+ true.
+ ] valueWithTimeout: 3 seconds) isNil.
+
+ self assert: timeouted not.
+ self assert: debugger isConnected not.
+
+ "Created: / 24-06-2014 / 09:06:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (format): / 06-09-2014 / 02:16:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/GDBDebuggerTestsS.st Sat Feb 28 08:34:19 2015 +0100
@@ -0,0 +1,129 @@
+"{ Package: 'jv:libgdbs/tests' }"
+
+"{ NameSpace: Smalltalk }"
+
+GDBDebuggerTestCase subclass:#GDBDebuggerTestsS
+ instanceVariableNames:'simulator'
+ classVariableNames:'DefaultWaitForTimeout'
+ poolDictionaries:''
+ category:'GDB-Core-Tests'
+!
+
+!GDBDebuggerTestsS class methodsFor:'documentation'!
+
+documentation
+"
+ Tests for GDBDebugger (using simulator)
+
+ [author:]
+ Jan Vrany <jan.vrany@fit.cvut.cz>
+
+ [instance variables:]
+
+ [class variables:]
+
+ [see also:]
+
+"
+! !
+
+!GDBDebuggerTestsS class methodsFor:'initialization'!
+
+initialize
+ "Invoked at system start or when the class is dynamically loaded."
+
+ "/ please change as required (and remove this comment)
+
+ DefaultWaitForTimeout := 100.
+
+ "Modified: / 27-02-2015 / 11:43:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBDebuggerTestsS methodsFor:'running'!
+
+tearDown
+ simulator notNil ifTrue:[ simulator stop ].
+ debugger notNil ifTrue:[ debugger release ].
+
+ "Created: / 06-09-2014 / 02:17:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBDebuggerTestsS methodsFor:'tests - basic'!
+
+test_basic_02
+ simulator := GDBSimulatorProcess new record: GDBSimulatorResource session_factorial_01.
+ simulator start.
+ debugger := GDBDebugger newWithProcess: simulator.
+
+ "Created: / 24-06-2014 / 09:09:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 06-09-2014 / 02:18:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBDebuggerTestsS methodsFor:'tests - threads'!
+
+test_inferiors_01a
+ | tgevent tevent blocker |
+
+ blocker := Semaphore new.
+ simulator := GDBSimulatorProcess new record: GDBSimulatorResource session_factorial_01.
+ simulator start.
+ debugger := GDBDebugger newWithProcess: simulator.
+ debugger announcer when: GDBThreadGroupEvent do:[:ev |
+ tgevent := ev.
+ ].
+ debugger announcer when: GDBThreadEvent do:[:ev |
+ tevent := ev.
+ ].
+ debugger send: (GDBMI_file_exec_and_symbols new arguments: {'/home/jv/Private/Projects/SmalltalkX/sources/branches/jv1/build/jv/libgdbs/tests/c/factorial'}).
+ debugger send: (GDBCLICommand new value: 'b factorial').
+
+ self assert: debugger inferiors size == 1.
+ self assert: debugger inferiors anElement id = 'i1'.
+ "/ No, following won't work as thread-group-added event is
+ "/ emited before we register the handler above!!
+ "/ self assert: debugger inferiors anElement == event threadGroup.
+
+ self
+ do:[ debugger send: (GDBCLICommand new value: 'r') ]
+ thenWaitFor: GDBStoppedEvent.
+
+ self assert: tgevent notNil.
+ self assert: tevent notNil.
+ self assert: debugger inferiors size == 1.
+ self assert: debugger inferiors anElement pid = 7719.
+ self assert: debugger inferiors anElement == tgevent threadGroup.
+ self assert: debugger inferiors anElement threads size == 1.
+ self assert: debugger inferiors anElement threads anElement == tevent thread.
+ self assert: debugger inferiors anElement threads anElement isTerminated not.
+ self assert: debugger inferiors anElement threads anElement isRunning not.
+ self assert: debugger inferiors anElement threads anElement isStopped.
+ self assert: debugger inferiors anElement threads anElement stack size == 2.
+
+ tgevent := tevent := nil.
+
+ debugger send: (GDBCLICommand new value: 'del 1').
+ tgevent := self
+ do:[ debugger send: (GDBCLICommand new value: 'c') ]
+ thenWaitFor: GDBThreadGroupExitedEvent.
+
+ self assert: tgevent notNil.
+ self assert: debugger inferiors size == 1.
+ self assert: debugger inferiors anElement exitCode = 23.
+ self assert: debugger inferiors anElement == tgevent threadGroup.
+ "/ When thread group exits, all it's threads are dead so
+ "/ inferior threads should return an empty collection.
+ self assert: debugger inferiors anElement threads isEmptyOrNil.
+
+ "Created: / 07-09-2014 / 13:37:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 27-02-2015 / 12:42:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBDebuggerTestsS class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
+
+GDBDebuggerTestsS initialize!
--- a/tests/Make.proto Fri Feb 27 16:47:55 2015 +0100
+++ b/tests/Make.proto Sat Feb 28 08:34:19 2015 +0100
@@ -130,11 +130,14 @@
# BEGINMAKEDEPEND --- do not remove this line; make depend needs it
-$(OUTDIR)GDBDebuggerTests.$(O) GDBDebuggerTests.$(H): GDBDebuggerTests.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)GDBDebuggeesResource.$(O) GDBDebuggeesResource.$(H): GDBDebuggeesResource.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestResource.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)GDBDebuggerTestCase.$(O) GDBDebuggerTestCase.$(H): GDBDebuggerTestCase.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)GDBInternalPipeStreamTests.$(O) GDBInternalPipeStreamTests.$(H): GDBInternalPipeStreamTests.st $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)GDBMIParserTests.$(O) GDBMIParserTests.$(H): GDBMIParserTests.st $(INCLUDE_TOP)/jv/libgdbs/GDBCommandStatus.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)GDBSimulatorProcessTests.$(O) GDBSimulatorProcessTests.$(H): GDBSimulatorProcessTests.st $(INCLUDE_TOP)/jv/libgdbs/GDBCommandStatus.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
$(OUTDIR)jv_libgdbs_tests.$(O) jv_libgdbs_tests.$(H): jv_libgdbs_tests.st $(INCLUDE_TOP)/stx/libbasic/LibraryDefinition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)GDBDebuggerTestsR.$(O) GDBDebuggerTestsR.$(H): GDBDebuggerTestsR.st $(INCLUDE_TOP)/jv/libgdbs/tests/GDBDebuggerTestCase.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)GDBDebuggerTestsS.$(O) GDBDebuggerTestsS.$(H): GDBDebuggerTestsS.st $(INCLUDE_TOP)/jv/libgdbs/tests/GDBDebuggerTestCase.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestAsserter.$(H) $(INCLUDE_TOP)/stx/goodies/sunit/TestCase.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
# ENDMAKEDEPEND --- do not remove this line
--- a/tests/Make.spec Fri Feb 27 16:47:55 2015 +0100
+++ b/tests/Make.spec Sat Feb 28 08:34:19 2015 +0100
@@ -51,21 +51,27 @@
STCWARNINGS=-warnNonStandard
COMMON_CLASSES= \
- GDBDebuggerTests \
+ GDBDebuggeesResource \
+ GDBDebuggerTestCase \
GDBInternalPipeStreamTests \
GDBMIParserTests \
GDBSimulatorProcessTests \
jv_libgdbs_tests \
+ GDBDebuggerTestsR \
+ GDBDebuggerTestsS \
COMMON_OBJS= \
- $(OUTDIR_SLASH)GDBDebuggerTests.$(O) \
+ $(OUTDIR_SLASH)GDBDebuggeesResource.$(O) \
+ $(OUTDIR_SLASH)GDBDebuggerTestCase.$(O) \
$(OUTDIR_SLASH)GDBInternalPipeStreamTests.$(O) \
$(OUTDIR_SLASH)GDBMIParserTests.$(O) \
$(OUTDIR_SLASH)GDBSimulatorProcessTests.$(O) \
$(OUTDIR_SLASH)jv_libgdbs_tests.$(O) \
+ $(OUTDIR_SLASH)GDBDebuggerTestsR.$(O) \
+ $(OUTDIR_SLASH)GDBDebuggerTestsS.$(O) \
--- a/tests/abbrev.stc Fri Feb 27 16:47:55 2015 +0100
+++ b/tests/abbrev.stc Sat Feb 28 08:34:19 2015 +0100
@@ -1,8 +1,11 @@
# automagically generated by the project definition
# this file is needed for stc to be able to compile modules independently.
# it provides information about a classes filename, category and especially namespace.
-GDBDebuggerTests GDBDebuggerTests jv:libgdbs/tests 'GDB-Core-Tests' 1
+GDBDebuggeesResource GDBDebuggeesResource jv:libgdbs/tests 'GDB-Core-Tests' 1
+GDBDebuggerTestCase GDBDebuggerTestCase jv:libgdbs/tests 'GDB-Core-Tests' 1
GDBInternalPipeStreamTests GDBInternalPipeStreamTests jv:libgdbs/tests 'GDB-Support-Tests' 1
GDBMIParserTests GDBMIParserTests jv:libgdbs/tests 'GDB-Private-Tests' 1
GDBSimulatorProcessTests GDBSimulatorProcessTests jv:libgdbs/tests 'GDB-Private-Tests' 1
jv_libgdbs_tests jv_libgdbs_tests jv:libgdbs/tests '* Projects & Packages *' 3
+GDBDebuggerTestsR GDBDebuggerTestsR jv:libgdbs/tests 'GDB-Core-Tests' 1
+GDBDebuggerTestsS GDBDebuggerTestsS jv:libgdbs/tests 'GDB-Core-Tests' 1
--- a/tests/bc.mak Fri Feb 27 16:47:55 2015 +0100
+++ b/tests/bc.mak Sat Feb 28 08:34:19 2015 +0100
@@ -77,11 +77,14 @@
# BEGINMAKEDEPEND --- do not remove this line; make depend needs it
-$(OUTDIR)GDBDebuggerTests.$(O) GDBDebuggerTests.$(H): GDBDebuggerTests.st $(INCLUDE_TOP)\stx\goodies\sunit\TestAsserter.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestCase.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)GDBDebuggeesResource.$(O) GDBDebuggeesResource.$(H): GDBDebuggeesResource.st $(INCLUDE_TOP)\stx\goodies\sunit\TestAsserter.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestResource.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)GDBDebuggerTestCase.$(O) GDBDebuggerTestCase.$(H): GDBDebuggerTestCase.st $(INCLUDE_TOP)\stx\goodies\sunit\TestAsserter.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestCase.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)GDBInternalPipeStreamTests.$(O) GDBInternalPipeStreamTests.$(H): GDBInternalPipeStreamTests.st $(INCLUDE_TOP)\stx\goodies\sunit\TestAsserter.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestCase.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)GDBMIParserTests.$(O) GDBMIParserTests.$(H): GDBMIParserTests.st $(INCLUDE_TOP)\jv\libgdbs\GDBCommandStatus.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestAsserter.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestCase.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)GDBSimulatorProcessTests.$(O) GDBSimulatorProcessTests.$(H): GDBSimulatorProcessTests.st $(INCLUDE_TOP)\jv\libgdbs\GDBCommandStatus.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestAsserter.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestCase.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
$(OUTDIR)jv_libgdbs_tests.$(O) jv_libgdbs_tests.$(H): jv_libgdbs_tests.st $(INCLUDE_TOP)\stx\libbasic\LibraryDefinition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)GDBDebuggerTestsR.$(O) GDBDebuggerTestsR.$(H): GDBDebuggerTestsR.st $(INCLUDE_TOP)\jv\libgdbs\tests\GDBDebuggerTestCase.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestAsserter.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestCase.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)GDBDebuggerTestsS.$(O) GDBDebuggerTestsS.$(H): GDBDebuggerTestsS.st $(INCLUDE_TOP)\jv\libgdbs\tests\GDBDebuggerTestCase.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestAsserter.$(H) $(INCLUDE_TOP)\stx\goodies\sunit\TestCase.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
# ENDMAKEDEPEND --- do not remove this line
--- a/tests/jv_libgdbs_tests.st Fri Feb 27 16:47:55 2015 +0100
+++ b/tests/jv_libgdbs_tests.st Sat Feb 28 08:34:19 2015 +0100
@@ -31,7 +31,7 @@
^ #(
#'jv:libgdbs' "GDBCommandStatus - shared pool used by GDBMIParserTests"
- #'stx:goodies/sunit' "TestAsserter - superclass of GDBDebuggerTests"
+ #'stx:goodies/sunit' "TestAsserter - superclass of GDBDebuggeesResource"
#'stx:libbasic' "LibraryDefinition - superclass of jv_libgdbs_tests"
)
!
@@ -71,11 +71,14 @@
^ #(
"<className> or (<className> attributes...) in load order"
- GDBDebuggerTests
+ GDBDebuggeesResource
+ GDBDebuggerTestCase
GDBInternalPipeStreamTests
GDBMIParserTests
GDBSimulatorProcessTests
#'jv_libgdbs_tests'
+ GDBDebuggerTestsR
+ GDBDebuggerTestsS
)
!
--- a/tests/libInit.cc Fri Feb 27 16:47:55 2015 +0100
+++ b/tests/libInit.cc Sat Feb 28 08:34:19 2015 +0100
@@ -27,11 +27,14 @@
void _libjv_libgdbs_tests_Init(pass, __pRT__, snd)
OBJ snd; struct __vmData__ *__pRT__; {
__BEGIN_PACKAGE2__("libjv_libgdbs_tests", _libjv_libgdbs_tests_Init, "jv:libgdbs/tests");
-_GDBDebuggerTests_Init(pass,__pRT__,snd);
+_GDBDebuggeesResource_Init(pass,__pRT__,snd);
+_GDBDebuggerTestCase_Init(pass,__pRT__,snd);
_GDBInternalPipeStreamTests_Init(pass,__pRT__,snd);
_GDBMIParserTests_Init(pass,__pRT__,snd);
_GDBSimulatorProcessTests_Init(pass,__pRT__,snd);
_jv_137libgdbs_137tests_Init(pass,__pRT__,snd);
+_GDBDebuggerTestsR_Init(pass,__pRT__,snd);
+_GDBDebuggerTestsS_Init(pass,__pRT__,snd);
__END_PACKAGE__();