Home > Net >  Invoke and control GDB from perl
Invoke and control GDB from perl

Time:04-12

I'm trying to write some script in perl for control of GDB debugging process. In following code I'm able to run GDB and pass some MI2 command, but I cannot catch the output from GDB:

open(G, "| gdb -n -q --interpreter=mi2") || die("error opening gdb");
syswrite(G, "-file-exec-and-symbols ./a.out\n");
$x = sysread(G, $resp, 4096);
printf("x: %u\n", $x);
printf("resp: '%s'\n", $resp)

and the result is:

x: 0
resp: ''
=thread-group-added,id="i1"
(gdb) 
^done
(gdb) 

The problem here is that GDB prints output '=thread-group-added,id="i1"' directly to the tty so I cannot catch it in my perl script for further interpretation. I'd like to catch the output from GDB to some variable and interprete it. As can be seen in the output sysread() procedure didn't read anything ("x: 0"). How can I do this?

CodePudding user response:

That opens the gdb process only to feed (replace) its STDIN, not to also read its output. The G is the write-end of a pipe. One can't have both with open, see pipe-open in open.

Instead, use a library which provides both, like IPC::Run.

use warnings;
use strict;
use feature 'say';

use IPC::Run qw(run); 

run [ qw(gdb -n -q --interpreter=mi2) ], \my $stdin, \my $so, \my $se; 

say "out = $so" if $so;    
say "err = $se" if $se;

This prints lines out = =thread-group-added,id="i1" and (gdb).

Assign to $stdin to write to the program's STDIN, and read its standard output/error from $so and/or $se in the end (there are ways to have it as it's emitted). The module can do a whole lot more, see docs.

  • Related