More work on variables + tests
authorJan Vrany <jan.vrany@fit.cvut.cz>
Sat, 28 Feb 2015 08:34:19 +0100
changeset 56 20989de12cfb
parent 55 437ee6413c74
child 57 f27c9f059a08
More work on variables + tests
GDBDebugger.st
GDBFrame.st
GDBMI_var_create.st
GDBTransientObject.st
GDBVariable.st
tests/GDBDebuggeesResource.st
tests/GDBDebuggerTestCase.st
tests/GDBDebuggerTests.st
tests/GDBDebuggerTestsR.st
tests/GDBDebuggerTestsS.st
tests/Make.proto
tests/Make.spec
tests/abbrev.stc
tests/bc.mak
tests/jv_libgdbs_tests.st
tests/libInit.cc
--- 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__();