// Short example on how to spawn a gdb an send // commands to it and get output back from it. // by Fredrik Öhrström and given to the public domain. #include void startDebugger (); void stopDebugger (); char gdbRead (); void gdbWrite (char c); void readUntilPrompt (unsigned char *data); // If data is NULL copy to stdout void writeDebugger (unsigned char*cmd, unsigned char* answer); int fd_to_debugger, fd_from_debugger, fd_err_from_debugger; void gdbWrite (char c) { write (fd_to_debugger, &c, 1); fsync (fd_to_debugger); } char gdbRead () { char c; read (fd_from_debugger, &c, 1); return c; } void writeDebugger (unsigned char*cmd, unsigned char *answer) { unsigned char a[10000]; if (answer==NULL) answer = a; fprintf (stderr, "COMMAND>%s\n", cmd); write (fd_to_debugger, cmd, strlen (cmd)); write (fd_to_debugger, "\n", 1); fsync (fd_to_debugger); readUntilPrompt (answer); fprintf (stderr, "******\n%s\n******\n", answer); } void readUntilPrompt (unsigned char *data) { char buf[256], c; char *str = "(gdb)"; int nof_read, n = strlen (str); if (n>255) exit(-1); memset (buf, 0, 256); while (1) { memmove(buf, buf+1, n-1); nof_read = read (fd_from_debugger, &c, 1); if (nof_read!=1) break; buf[n-1] = c; if (data!=NULL) { *data = c; data++; } else { printf ("%c", c); } if (buf[n-1]==0) exit(-1); if (!strcmp (str, buf)) break; } if (data!=NULL) *data = 0; } void stopDebugger () { close(fd_to_debugger); close(fd_err_from_debugger); close(fd_from_debugger); } void startDebugger () { unsigned char tmp_string[1024]; int stdin_pipe[2]; int stdout_pipe[2]; int stderr_pipe[2]; int fork_result; int n, i; if( (pipe(stdin_pipe) != 0) || (pipe(stdout_pipe) != 0) || (pipe(stderr_pipe) != 0)) { fprintf (stderr, "Could not create pipes!\n"); exit (-1); } fork_result = fork(); if(fork_result == -1) { fprintf(stderr, "Fork Failure\n"); exit(-1); } if(fork_result == 0) { // We are child close(0); // Close childs stdin dup(stdin_pipe[0]); // Child now has STDIN that is stdin_pipe[0] close(stdin_pipe[0]); close(stdin_pipe[1]); close(1); // Close childs stdout dup(stdout_pipe[1]); // Child now has STDOUT that is stdout_pipe[1] //setvbuf (stdout, (char*)NULL, _IONBF, 0); // Do not buffer stdout! close(stdout_pipe[0]); close(stdout_pipe[1]); close(2); // Close childs STDERR dup(stderr_pipe[1]); close(stderr_pipe[0]); close(stderr_pipe[1]); execlp("gdb","gdb", (char *)0); // If we get here, the execlp failed! fprintf (stderr, "Execution of gdb failed!\n"); exit(-1); } else { fd_to_debugger = stdin_pipe[1]; // Write to stdin fd_from_debugger = stdout_pipe[0]; // Read from stdout fd_err_from_debugger = stderr_pipe[0]; // Read from stderr close(stdin_pipe[0]); // No reads from stdin close(stdout_pipe[1]); // No writes to stdout close(stderr_pipe[1]); // No writes to stderr readUntilPrompt (NULL); } } int main (int argc, char **argv) { startDebugger(); writeDebugger("info shared", NULL); stopDebugger(); }