More work on GDB session recorder.
"{ Package: 'jv:libgdbs' }"
Object subclass:#GDBDebugger
instanceVariableNames:'connection commandSequenceNumber inferiorStateSequenceNumber'
classVariableNames:''
poolDictionaries:'GDBCommandStatus'
category:'GDB-Core'
!
!GDBDebugger class methodsFor:'instance creation'!
new
^ self newWithProcess: GDBUnixProcess new
"Modified: / 20-06-2014 / 21:44:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
newWithProcess: aGDBProcess
^ self basicNew initializeWithProcess: aGDBProcess
"Created: / 20-06-2014 / 21:44:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger methodsFor:'accessing'!
announcer
^ connection eventAnnouncer.
"Created: / 02-06-2014 / 23:06:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
inferiorStderr
^ connection inferiorPTY master
"Created: / 09-06-2014 / 10:01:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 09-06-2014 / 18:26:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
inferiorStdin
^ connection inferiorPTY master
"Created: / 09-06-2014 / 10:00:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 09-06-2014 / 18:27:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
inferiorStdout
^ connection inferiorPTY master
"Created: / 09-06-2014 / 10:01:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 09-06-2014 / 18:27:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger methodsFor:'accessing-private'!
currentInferiorStateSequnceNumber
^ inferiorStateSequenceNumber
"Created: / 19-06-2014 / 22:22:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
nextCommandSequnceNumber
commandSequenceNumber := commandSequenceNumber + 1.
commandSequenceNumber == SmallInteger maxVal ifTrue:[
commandSequenceNumber := 0.
].
^ commandSequenceNumber
"Created: / 02-06-2014 / 23:48:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
nextInferiorStateSequnceNumber
inferiorStateSequenceNumber := inferiorStateSequenceNumber + 1.
inferiorStateSequenceNumber == SmallInteger maxVal ifTrue:[
inferiorStateSequenceNumber := 0.
].
^ inferiorStateSequenceNumber
"Created: / 02-06-2014 / 23:48:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger methodsFor:'commands'!
send: aGDBCommand
^ self send: aGDBCommand wait: true.
"Created: / 03-06-2014 / 00:10:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
send: aGDBCommand wait: aBoolean
"Sends given command to GDB. If `aBoolean` is true, wait for
command to finish. Otherwise, return immediately."
| token blocker releaser |
token := self nextCommandSequnceNumber.
aGDBCommand token: token.
aBoolean ifTrue:[
releaser := [ :ev |
ev token == token ifTrue:[
self announcer unsubscribe: releaser.
blocker signal.
]].
blocker := Semaphore new.
self announcer when: GDBCommandResultEvent do: releaser.
connection pushEvent: (GDBCommandEvent new command: aGDBCommand).
blocker wait.
] ifFalse:[
connection pushEvent: (GDBCommandEvent new command: aGDBCommand).
]
"Created: / 02-06-2014 / 23:45:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 04-06-2014 / 09:32:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger methodsFor:'event handling'!
onCommand: aGDBCommandEvent
connection send: aGDBCommandEvent command.
"Created: / 02-06-2014 / 23:38:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 20-06-2014 / 22:09:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
onCommandResult: aGDBCommandResultEvent
aGDBCommandResultEvent result status == CommandStatusExit ifTrue:[
connection pushEvent: GDBExitEvent new.
].
"Created: / 02-06-2014 / 23:40:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 04-06-2014 / 09:30:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
onExecutionEvent: aGDBExecutionEvent
self nextInferiorStateSequnceNumber.
"Created: / 19-06-2014 / 22:21:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
onExit: aGDBExitEvent
self release.
"Created: / 03-06-2014 / 00:36:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 04-06-2014 / 09:28:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger methodsFor:'finalization'!
finalize
self release.
"Created: / 26-05-2014 / 21:23:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger methodsFor:'initialize & release'!
initializeWithProcess: aGDBProcess
self registerForFinalization.
connection := GDBConnection newWithProcess: aGDBProcess.
commandSequenceNumber := 0.
inferiorStateSequenceNumber := 0.
self subscribe.
connection eventPumpStart.
connection eventDispatchStart.
Delay waitForMilliseconds:100.
"/ self send: (GDBMICommand inferiorTtySet: driver inferiorPTY name).
self send: (GDBMI_inferior_tty_set arguments: { connection inferiorPTY name })
"Created: / 20-06-2014 / 21:45:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 23-06-2014 / 23:44:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
release
connection notNil ifTrue:[
self unsubscribe.
connection release.
connection := nil.
].
"Created: / 26-05-2014 / 21:24:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 20-06-2014 / 22:08:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
subscribe
connection eventAnnouncerInternal
when: GDBCommandEvent send: #onCommand: to: self;
when: GDBCommandResultEvent send: #onCommandResult: to: self;
when: GDBExitEvent send: #onExit: to: self;
when: GDBExecutionEvent send: #onExecutionEvent: to: self.
"Created: / 20-06-2014 / 22:07:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
unsubscribe
connection eventAnnouncerInternal unsubscribe: self
"Created: / 20-06-2014 / 22:07:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger methodsFor:'testing'!
isConnected
^ connection notNil
"Created: / 20-06-2014 / 22:12:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDebugger class methodsFor:'documentation'!
version_HG
^ '$Changeset: <not expanded> $'
! !