Use special PTY for inferior input/output...
...so gdb control streams are not interleaved with inferior's input/output.
--- a/GDB.st Wed Jun 04 09:37:08 2014 +0100
+++ b/GDB.st Mon Jun 09 10:28:46 2014 +0100
@@ -24,6 +24,26 @@
"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:[
--- a/GDBDriver.st Wed Jun 04 09:37:08 2014 +0100
+++ b/GDBDriver.st Mon Jun 09 10:28:46 2014 +0100
@@ -1,8 +1,9 @@
"{ Package: 'jv:libgdbs' }"
Object subclass:#GDBDriver
- instanceVariableNames:'pid input output eventAnnouncer eventQueue eventQueueLock
- eventQueueNotifier eventDispatchProcess eventPumpProcess'
+ instanceVariableNames:'pid debuggerInput debuggerOutput inferiorInput inferiorOutput
+ eventAnnouncer eventQueue eventQueueLock eventQueueNotifier
+ eventDispatchProcess eventPumpProcess'
classVariableNames:''
poolDictionaries:'GDBDebugFlags'
category:'GDB-Private'
@@ -11,19 +12,30 @@
!GDBDriver class methodsFor:'instance creation'!
-pid:pidArg input:inputArg output:outputArg
+debuggerPid:pidArg debuggerInput:inputArg debuggerOutput:outputArg inferiorInput:inferiorInputArg inferiorOutput:inferiorOutputArg
^ self new
- initializeWithPid:pidArg
- input:inputArg
- output:outputArg
+ initializeWithDebuggerPid:pidArg
+ debuggerInput:inputArg
+ debuggerOutput:outputArg
+ inferiorInput:inferiorInputArg
+ inferiorOutput:inferiorOutputArg
"Created: / 26-05-2014 / 13:35:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 09-06-2014 / 09:20:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBDriver methodsFor:'accessing'!
eventAnnouncer
^ eventAnnouncer
+!
+
+inferiorInput
+ ^ inferiorInput
+!
+
+inferiorOutput
+ ^ inferiorOutput
! !
!GDBDriver methodsFor:'event dispatching'!
@@ -115,9 +127,9 @@
command := aGDBCommandEvent command.
command token notNil ifTrue:[
- input nextPutAll: command token printString.
+ debuggerInput nextPutAll: command token printString.
].
- input nextPutLine: command asString.
+ debuggerInput nextPutLine: command asString.
"Created: / 02-06-2014 / 23:38:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
@@ -127,8 +139,8 @@
eventPumpLoop
| parser |
- parser := GDBParser on: output.
- [ output atEnd ] whileFalse:[
+ parser := GDBParser on: debuggerOutput.
+ [ debuggerOutput atEnd ] whileFalse:[
| eventset |
[
@@ -143,16 +155,16 @@
terminator := '(gdb)'.
i := 1.
- output notNil ifTrue:[
- [ output atEnd not and: [i <= terminator size ] ] whileTrue:[
- c := output next.
+ debuggerOutput notNil ifTrue:[
+ [ debuggerOutput atEnd not and: [i <= terminator size ] ] whileTrue:[
+ c := debuggerOutput next.
c == (terminator at: i) ifTrue:[
i := i + 1.
] ifFalse:[
i := 1.
].
].
- output next. "/ read nl.
+ debuggerOutput next. "/ read nl.
] ifFalse:[
^ self.
].
@@ -222,20 +234,23 @@
!GDBDriver methodsFor:'initialize & release'!
-initializeWithPid:pidArg input:inputArg output:outputArg
+initializeWithDebuggerPid:pidArg debuggerInput:inputArg debuggerOutput:outputArg inferiorInput:inferiorInputArg inferiorOutput:inferiorOutputArg
pid := pidArg.
- input := inputArg.
-
- output := outputArg.
+ debuggerInput := inputArg.
+ debuggerOutput := outputArg.
+ inferiorInput := inferiorInputArg.
+ inferiorOutput := inferiorOutputArg.
eventQueue := OrderedCollection new.
eventQueueLock := RecursionLock new.
eventQueueNotifier := Semaphore new.
eventAnnouncer := Announcer new.
-
- eventAnnouncer when: GDBCommandEvent send: #onCommand: to: self.
+ eventAnnouncer
+ when:GDBCommandEvent
+ send:#onCommand:
+ to:self.
"Created: / 26-05-2014 / 13:35:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 02-06-2014 / 23:39:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 09-06-2014 / 09:14:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
release
@@ -262,13 +277,13 @@
].
pid := nil.
eventQueueNotifier signalForAll.
- input notNil ifTrue:[
- input close.
- input := nil.
+ debuggerInput notNil ifTrue:[
+ debuggerInput close.
+ debuggerInput := nil.
].
- output notNil ifTrue:[
- output close.
- output := nil.
+ debuggerOutput notNil ifTrue:[
+ debuggerOutput close.
+ debuggerOutput := nil.
].
"Created: / 26-05-2014 / 21:31:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
--- a/GDBLauncher.st Wed Jun 04 09:37:08 2014 +0100
+++ b/GDBLauncher.st Mon Jun 09 10:28:46 2014 +0100
@@ -11,43 +11,76 @@
!GDBLauncher class methodsFor:'starting'!
startGDB
- | inputPipe input outputPipe output args controller pid |
+ | inputPipe input outputPipe output args controller pid inferiorOutput inferiorInput ptyTriple ptyName master slave|
+
+ OperatingSystem isUNIXlike ifTrue:[
+ "Use a pseudo-tty"
+ ptyTriple := OperatingSystem makePTY.
+
+ ptyName := ptyTriple at:3.
+
+ "/ pty at:1 is the master;
+ "/ pty at:2 is the slave
+ master := NonPositionableExternalStream forReadWriteToFileDescriptor:(ptyTriple at:1).
+ master buffered:false.
+
+ slave := NonPositionableExternalStream forReadWriteToFileDescriptor:(ptyTriple at:2).
+ slave close.
+
+ inferiorInput := inferiorOutput := master.
+ ] ifFalse:[
+ OperatingSystem isMSWINDOWSNTlike ifTrue:[
+ self error: 'Windows are not (yet) supported'
+ ] ifFalse:[
+ self error: 'Operating system not supported'
+ ]
+ ].
+
+
inputPipe := NonPositionableExternalStream makePipe.
input := inputPipe second.
-
outputPipe := NonPositionableExternalStream makePipe.
- output := outputPipe first.
-
- args := #('/usr/bin/gdb' '--interpreter' 'mi2').
-
- Processor monitor:[
- pid := OperatingSystem exec: args first withArguments:args
- environment: OperatingSystem getEnvironment
- fileDescriptors:{inputPipe first fileDescriptor . outputPipe second fileDescriptor . outputPipe second fileDescriptor}
- fork:true
- newPgrp:false
- inDirectory:Filename currentDirectory.
- controller := GDBDriver pid: pid input: input output: output.
- pid.
- ] action:[:stat |
- controller released: stat.
+ output := outputPipe first.
+ args := #( '/usr/bin/gdb' '--interpreter' 'mi2' ).
+ ptyName notNil ifTrue:[
+ args := args , { '-tty=', ptyName }.
].
-
+ Processor
+ monitor:[
+ pid := OperatingSystem
+ exec:args first
+ withArguments:args
+ environment:OperatingSystem getEnvironment
+ fileDescriptors:{
+ inputPipe first fileDescriptor.
+ outputPipe second fileDescriptor.
+ outputPipe second fileDescriptor
+ }
+ fork:true
+ newPgrp:false
+ inDirectory:Filename currentDirectory.
+ controller := GDBDriver
+ debuggerPid:pid
+ debuggerInput:input
+ debuggerOutput:output
+ inferiorInput:inferiorInput
+ inferiorOutput:inferiorOutput.
+ pid.
+ ]
+ action:[:stat | controller released:stat. ].
inputPipe first close.
outputPipe second close.
-
- pid isNil ifTrue:[
+ pid isNil ifTrue:[
input close.
output close.
- self error: 'Failed to launch gdb'.
+ self error:'Failed to launch gdb'.
^ self.
].
-
^ controller
"Created: / 26-05-2014 / 21:18:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 02-06-2014 / 23:04:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 09-06-2014 / 09:48:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!GDBLauncher class methodsFor:'documentation'!
--- a/GDBStatusEvent.st Wed Jun 04 09:37:08 2014 +0100
+++ b/GDBStatusEvent.st Mon Jun 09 10:28:46 2014 +0100
@@ -7,6 +7,7 @@
category:'GDB-Core-Events'
!
+
!GDBStatusEvent methodsFor:'testing'!
isStatusEvent
@@ -15,3 +16,10 @@
"Created: / 01-06-2014 / 23:38:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!GDBStatusEvent class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+! !
+
--- a/libgdbs.rc Wed Jun 04 09:37:08 2014 +0100
+++ b/libgdbs.rc Mon Jun 09 10:28:46 2014 +0100
@@ -25,7 +25,7 @@
VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
VALUE "ProductName", "LibraryName\0"
VALUE "ProductVersion", "6.2.4.0\0"
- VALUE "ProductDate", "Wed, 04 Jun 2014 08:34:53 GMT\0"
+ VALUE "ProductDate", "Mon, 09 Jun 2014 09:26:44 GMT\0"
END
END