jjh@telesoft.telesoft.com (Jim Hayes @wayward) (08/30/89)
Hi all, I'm working on a source-level debugger which runs on a Sun3 using SunOS 4.0. We spawn the target program (the program being debugged) using vfork(2) and keep control over it using ptrace(2). We want to have complete control over the child's terminal input and output so we can direct it to an i/o window we've set up; in order to do this we replace the child's stdin, stdout, and stderr descriptors with one end of a pipe, the other end of which the debugger watches. This works fine for the child's output: we check the pipe periodically using fstat(2), and when the child writes something onto the pipe we read it and display it to the window. But I sure can't figure out how to detect when the child is waiting for input. Right now we make the assumption that anything the user types while the child is running is intended for the child, and we send it down the pipe. This works ok, but it's not "right" and has several problems associated with it. Any suggestions? We're working under the restriction that we're not allowed to muck with the target's code (at least not much). I've beat my head against this one for quite a while now, so I'd greatly appreciate any help folks can offer. --Jim ------------------------------------------------------------------------------ "There's no problem so awful that you can't | Jim Hayes add some guilt to it and make it even worse!" | ...!ucsd!telesoft!jjh
richt@breakpoint.ksr.com (Rich Title) (09/02/89)
In article <469@telesoft.telesoft.com> jjh@telesoft.telesoft.com (Jim Hayes @wayward) writes: > >Hi all, > > I'm working on a source-level debugger which runs on a Sun3 using SunOS 4.0. >We spawn the target program (the program being debugged) using vfork(2) and keep >control over it using ptrace(2). We want to have complete control over the >child's terminal input and output so we can direct it to an i/o window we've >set up; in order to do this we replace the child's stdin, stdout, and stderr >descriptors with one end of a pipe, the other end of which the debugger watches. >This works fine for the child's output: we check the pipe periodically using >fstat(2), and when the child writes something onto the pipe we read it and >display it to the window. But I sure can't figure out how to detect when the >child is waiting for input. Right now we make the assumption that anything the >user types while the child is running is intended for the child, and we send it >down the pipe. This works ok, but it's not "right" and has several problems >associated with it. Any suggestions? > >--Jim I'm trying to figure out why you need to make the assumption you're making. Perhaps it's a limitation of the windowing system you're using - you can't collect input from the target i/o window (?), so you have to collect it from the debugger's stdin (?), so you have to make this assumption in order to figure out what input goes to the debugger and what input goes to the target program? Anyway, here's what I do in my debugger. This assumes you're using X-windows, so it may or may not help you... 1. Use "xterm" in slave mode as the program I/O window. When the user selects this window and types at it, that input goes to the target program (doesn't matter whether the target program was running at the time). When the target program writes output, it goes to this window. Using a terminal emulator such as "xterm" as the target window also has the advantage of working properly even if the target program does screen-oriented things (e.g., uses 'curses'). 2. Use pty's to transfer I/O between the target window and the target program. That way, the debugger doesn't have to sit in the middle watching file descriptors. In more detail: - Allocate a pty (see pty(4)). In other words, open the pair of files /dev/pty[p-r][0-f] and /dev/tty[p-r][0-f]. For example, /dev/ptyq3 and /dev/ttyq3. This gives you two file descriptors. Just for the sake of example, let's say these are file descriptors 5 and 6. - For the program I/O window, run 'xterm' in slave mode. I.e., you fork a process and exec "xterm" in that process. Give "xterm" the switch "-Sccn" where 'cc' is the 2 characters indicating what pty you are using, and 'n' is a number representing the pty file descriptor. So using the above example, you would run "xterm -Sq35 ...". - Then, when you fork the child process, before exec-ing the program being debugged, dup the tty file descriptor (6 in the above example), to 0, 1, and 2. The effect of all this is that input and output to the xterm appears as input/output on the tty file descriptor, which to the program being debugged is just the ordinary stdin, stdout, stderr. - Rich