Spawn a terminal for the debugger when needed if we are not already attached to one

This commit is contained in:
Michael Pavone committed 2015-07-26 01:11:04 -07:00
1 parent 25fc1e88de
commit bee8b42029
8 files changed
+175 -3

No files matched your search

+8 -3
View File
@@ -5,6 +5,7 @@ endif
ifeq ($(OS),Windows)
MEM:=mem_win.o
TERMINAL:=terminal_win.o
BLASTEM:=blastem.exe
CC:=wine gcc.exe
CFLAGS:=-O2 -std=gnu99 -Wreturn-type -Werror=return-type -Werror=implicit-function-declaration -I"C:/MinGW/usr/include/SDL2" -DGLEW_STATIC
@@ -14,6 +15,7 @@ CPU:=i686
else
MEM:=mem.o
TERMINAL:=terminal.o
BLASTEM:=blastem
ifeq ($(OS),Darwin)
@@ -99,7 +101,7 @@ Z80OBJS=z80inst.o z80_to_x86.o
AUDIOOBJS=ym2612.o psg.o wave.o
CONFIGOBJS=config.o tern.o util.o
MAINOBJS=blastem.o debug.o gdb_remote.o vdp.o render_sdl.o io.o romdb.o $(CONFIGOBJS) gst.o $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS)
MAINOBJS=blastem.o debug.o gdb_remote.o vdp.o render_sdl.o io.o romdb.o $(TERMINAL) $(CONFIGOBJS) gst.o $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS)
ifeq ($(CPU),x86_64)
CFLAGS+=-DX86_64 -m64
@@ -119,9 +121,12 @@ endif
ifeq ($(OS),Windows)
MAINOBJS+= glew32s.lib
ALL=$(BLASTEM)
else
ALL= dis zdis stateview vgmplay blastem termhelper
endif
all : dis zdis stateview vgmplay blastem
all : $(ALL)
$(BLASTEM) : $(MAINOBJS)
$(CC) -o $(BLASTEM) $(MAINOBJS) $(LDFLAGS)
@@ -188,4 +193,4 @@ vos_prog_info : vos_prog_info.o vos_program_module.o
vasmz80_mot -Fbin -spaces -o $@ $<
clean :
rm -rf dis trans stateview test_x86 gen_fib *.o
rm -rf $(ALL) trans ztestrun ztestgen *.o
+5
View File
@@ -8,6 +8,7 @@
#endif
#include "render.h"
#include "util.h"
#include "terminal.h"
static bp_def * breakpoints = NULL;
static bp_def * zbreakpoints = NULL;
@@ -287,6 +288,7 @@ z80_context * zdebugger(z80_context * context, uint16_t address)
static uint16_t branch_t;
static uint16_t branch_f;
z80inst inst;
init_terminal();
//Check if this is a user set breakpoint, or just a temporary one
bp_def ** this_bp = find_breakpoint(&zbreakpoints, address);
if (*this_bp) {
@@ -473,6 +475,9 @@ m68k_context * debugger(m68k_context * context, uint32_t address)
static uint32_t branch_t;
static uint32_t branch_f;
m68kinst inst;
init_terminal();
sync_components(context, 0);
//probably not necessary, but let's play it safe
address &= 0xFFFFFF;
+44
View File
@@ -0,0 +1,44 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "terminal.h"
char buf[4096];
void copy_data(int to, int from)
{
ssize_t bytes = read(from, buf, sizeof(buf));
while (bytes > 0)
{
ssize_t written = write(to, buf, bytes);
if (written == -1) {
exit(1);
}
bytes -= written;
}
}
int main(int argc, char **argv)
{
//these will block so order is important
int input_fd = open(INPUT_PATH, O_WRONLY);
int output_fd = open(OUTPUT_PATH, O_RDONLY);
fd_set read_fds;
FD_ZERO(&read_fds);
for (;;)
{
FD_SET(STDIN_FILENO, &read_fds);
FD_SET(output_fd, &read_fds);
select(output_fd+1, &read_fds, NULL, NULL, NULL);
if (FD_ISSET(STDIN_FILENO, &read_fds)) {
copy_data(input_fd, STDIN_FILENO);
}
if (FD_ISSET(output_fd, &read_fds)) {
copy_data(STDOUT_FILENO, output_fd);
}
}
return 0;
}
+65
View File
@@ -0,0 +1,65 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include "util.h"
#include "terminal.h"
pid_t child;
void cleanup_terminal()
{
kill(child, SIGKILL);
unlink(INPUT_PATH);
unlink(OUTPUT_PATH);
}
void init_terminal()
{
static char init_done;
if (!init_done) {
if (!(isatty(STDIN_FILENO) && isatty(STDOUT_FILENO))) {
#ifndef __APPLE__
//check to see if x-terminal-emulator exists, just use xterm if it doesn't
char *term = system("which x-terminal-emulator > /dev/null") ? "xterm" : "x-terminal-emulator";
#endif
//get rid of FIFO's if they already exist
unlink(INPUT_PATH);
unlink(OUTPUT_PATH);
//create FIFOs for talking to helper process in terminal app
mkfifo(INPUT_PATH, 0666);
mkfifo(OUTPUT_PATH, 0666);
//close existing file descriptors
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
child = fork();
if (child == -1) {
//error, oh well
warning("Failed to fork for terminal spawn");
} else if (!child) {
//child process, exec our terminal emulator
#ifdef __APPLE__
execlp("open", "open", "./termhelper", NULL);
#else
execlp(term, term, "-title", "BlastEm Debugger", "-e", "./termhelper", NULL);
#endif
} else {
//connect to the FIFOs, these will block so order is important
open(INPUT_PATH, O_RDONLY);
open(OUTPUT_PATH, O_WRONLY);
atexit(cleanup_terminal);
if (-1 == dup(STDOUT_FILENO)) {
fatal_error("failed to dup STDOUT to STDERR after terminal fork");
}
}
}
init_done = 1;
}
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef TERMINAL_H_
#define TERMINAL_H_
void init_terminal();
#define INPUT_PATH "/tmp/blastem_input"
#define OUTPUT_PATH "/tmp/blastem_output"
#endif //TERMINAL_H_
+13
View File
@@ -0,0 +1,13 @@
#include <windows.h>
#include <stdio.h>
void init_terminal()
{
static init_done;
if (!init_done) {
AllocConsole();
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
}
}
+29
View File
@@ -116,6 +116,35 @@ void fatal_error(char *format, ...)
exit(1);
}
void warning(char *format, ...)
{
va_list args;
va_start(args, format);
#ifndef _WIN32
if (headless || (isatty(STDERR_FILENO) && isatty(STDIN_FILENO))) {
vfprintf(stderr, format, args);
} else {
#endif
size_t size = strlen(format) * 2;
char *buf = malloc(size);
size_t actual = vsnprintf(buf, size, format, args);
if (actual >= size) {
actual++;
free(buf);
buf = malloc(actual);
va_end(args);
va_start(args, format);
vsnprintf(buf, actual, format, args);
}
fputs(buf, stderr);
render_infobox("BlastEm Info", buf);
free(buf);
#ifndef _WIN32
}
#endif
va_end(args);
}
void info_message(char *format, ...)
{
va_list args;
+2
View File
@@ -29,5 +29,7 @@ char * readlink_alloc(char * path);
void fatal_error(char *format, ...);
//Prints an information message to stdout and to a message box if not in headless mode and not attached to a console
void info_message(char *format, ...);
//Prints an information message to stderr and to a message box if not in headless mode and not attached to a console
void warning(char *format, ...);
#endif //UTIL_H_