Issue
i'm try to make a C program to interact with GDB using GBD MI protocol.
First a try to handle the subprocess by myself, but i fund the project subprocess.h and start to use it.
In the follow program, I can spawn the new process, read the stdout
and stderr
, but when i try to send something to stdin isn't work.
Getting the return from fprintf
, it is possible to see that 18 bytes are written to the file handle p_stdin, but I do not get any response. Is there any way to check if the stdin handle is correct?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#define BUFFER_SIZE 32
#include "subprocess.h"
int main(void) {
const char *command_line[] = {"gdb", "--nx", "-quiet","--interpreter=mi3", NULL};
struct subprocess_s gdb_sp;
printf("Starting new process\n");
int gdb_status = subprocess_create(command_line, subprocess_option_search_user_path | subprocess_option_inherit_environment , &gdb_sp);
if(gdb_status != 0) {
fprintf(stderr, "Erro: can't open GDB, check if its is installed\n");
return -1;
}
printf("Started\n");
FILE *p_stdout = subprocess_stdout(&gdb_sp);
FILE *p_stderr = subprocess_stderr(&gdb_sp);
char stdout_buf[BUFFER_SIZE];
char stderr_buf[BUFFER_SIZE];
memset(stdout_buf, 0, sizeof(stdout_buf));
memset(stderr_buf, 0, sizeof(stderr_buf));
fgets(stdout_buf, BUFFER_SIZE, p_stdout);
printf("%s", stdout_buf);
fgets(stdout_buf, BUFFER_SIZE, p_stdout);
printf("%s", stdout_buf);
FILE *p_stdin = subprocess_stdin(&gdb_sp);
int a = fprintf(p_stdin, "-break-insert main");
printf("%d\n", a);
fgets(stdout_buf, BUFFER_SIZE, p_stdout);
printf("%s", stdout_buf);
int ret = -1;
subprocess_join(&gdb_sp, &ret);
if(ret != 0 ) {
fprintf(stderr, "Erro: can't join GDB process!\n");
return -1;
}
assert(!subprocess_destroy(&gdb_sp));
printf("Press KEY to exit!");
getchar();
return EXIT_SUCCESS;
}
If you want to run on your machine, put the code above and the subprocess.h in the same folder, you can use the follow CMakeLists.txt to compile.
cmake_minimum_required(VERSION 3.0)
project(gdb-mi)
set (CMAKE_C_STANDARD 99)
file(GLOB PROJECT_HEADERS *.h)
file(GLOB PROJECT_SOURCES *.c)
source_group("headers" FILES ${PROJECT_HEADERS})
source_group("sources" FILES ${PROJECT_SOURCES})
add_definitions(-DPROJECT_SOURCE_DIR=\"${PROJECT_SOURCE_DIR}\")
add_executable(${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS})
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PROJECT_NAME})
Tested on:
- Void Linux: gcc 12.2.0
- WSL2 Ubuntu 20.04: gcc 9.4.0
- Windows 11: MSVC 19.38.33134.0
I would like to be able to interact with GDB in a simple way using C, if you have a good example of how to do this communication, for Linux and Windows it would help a lot.
Solution
Getting the return from fprintf, it is possible to see that 18 bytes are written to the file handle p_stdin, but I do not get any response.
The subprocess.h
doesn't appear to set any buffering, and documentation for it doesn't even mention buffering.
By default, stdio
on pipes is fully buffered, and you need to call fflush(p_stdin)
to actually send your command to the subprocess.
Answered By - Employed Russian Answer Checked By - Katrina (WPSolving Volunteer)