GDB.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Mon, 09 Jun 2014 10:28:46 +0100
changeset 10 f04a22c9b16c
parent 9 5cc8797f6523
child 11 474fbb650afe
permissions -rw-r--r--
Use special PTY for inferior input/output... ...so gdb control streams are not interleaved with inferior's input/output.

"{ Package: 'jv:libgdbs' }"

Object subclass:#GDB
	instanceVariableNames:'driver commandSequenceNumber snapshotSequenceNumber'
	classVariableNames:''
	poolDictionaries:'GDBCommandStatus'
	category:'GDB-Core'
!


!GDB class methodsFor:'instance creation'!

new
    "return an initialized instance"

    ^ self basicNew initialize.
! !

!GDB methodsFor:'accessing'!

announcer
    ^ driver eventAnnouncer.

    "Created: / 02-06-2014 / 23:06:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

inferiorStderr
    ^ driver inferiorOutput

    "Created: / 09-06-2014 / 10:01:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

inferiorStdin
    ^ driver inferiorInput

    "Created: / 09-06-2014 / 10:00:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

inferiorStdout
    ^ driver inferiorOutput

    "Created: / 09-06-2014 / 10:01:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!GDB methodsFor:'accessing-private'!

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>"
!

nextSnapshotSequnceNumber
    snapshotSequenceNumber := snapshotSequenceNumber + 1.
    snapshotSequenceNumber == SmallInteger maxVal ifTrue:[ 
        snapshotSequenceNumber := 0.
    ].
    ^ snapshotSequenceNumber

    "Created: / 02-06-2014 / 23:48:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!GDB 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.
        driver pushEvent: (GDBCommandEvent new command: aGDBCommand).
        blocker wait.
    ] ifFalse:[
        driver 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>"
! !

!GDB methodsFor:'event handling'!

onCommandResult: aGDBCommandResultEvent
    aGDBCommandResultEvent result status == CommandStatusExit ifTrue:[ 
        driver 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>"
!

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>"
! !

!GDB methodsFor:'finalization'!

finalize
    self release.

    "Created: / 26-05-2014 / 21:23:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!GDB methodsFor:'initialize & release'!

initialize
    self registerForFinalization.
    driver := GDBLauncher startGDB.

    commandSequenceNumber := 0.
    snapshotSequenceNumber := 0.

    self announcer
        when: GDBCommandResultEvent     send: #onCommandResult: to: self;
        when: GDBExitEvent              send: #onExit: to: self.

    driver eventPumpStart.
    driver eventDispatchStart.

    "Created: / 26-05-2014 / 21:23:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 03-06-2014 / 00:35:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

release
    driver notNil ifTrue:[ 
        driver release.
        driver := nil.
    ].

    "Created: / 26-05-2014 / 21:24:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!GDB class methodsFor:'documentation'!

version_HG

    ^ '$Changeset: <not expanded> $'
! !