mirror of
https://github.com/radareorg/r2ghidra.git
synced 2026-11-07 06:25:57 -10:00
Preserve console filtering for timeout worker output
This commit is contained in:
1 parent
9b7969e190
commit
083a19a9d7
2 files changed
+64
-22
No files matched your search
+60
-20
@@ -22,6 +22,7 @@
|
||||
|
||||
#if R2__UNIX__ && !defined(__wasi__)
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
@@ -845,40 +846,79 @@ static void _cmd(RCore *core, const char *input) {
|
||||
}
|
||||
pid_t pid = r_sys_fork ();
|
||||
if (pid < 0) {
|
||||
close (fds[0]);
|
||||
close (fds[1]);
|
||||
R_LOG_ERROR ("Cannot fork");
|
||||
return;
|
||||
}
|
||||
if (pid == 0) {
|
||||
close (fds[0]);
|
||||
r_cons_reset (core->cons);
|
||||
runcmd (core, input);
|
||||
r_cons_flush (core->cons);
|
||||
fflush (stdout);
|
||||
write (fds[1], "\x12", 1);
|
||||
exit (0);
|
||||
size_t size = 0;
|
||||
const char *buf = r_cons_get_buffer (core->cons, &size);
|
||||
while (size > 0) {
|
||||
ssize_t n = write (fds[1], buf, size);
|
||||
if (n < 0 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
if (n <= 0) {
|
||||
_exit (1);
|
||||
}
|
||||
buf += n;
|
||||
size -= n;
|
||||
}
|
||||
_exit (0);
|
||||
} else {
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
struct pollfd pfd = { fds[0], POLLIN, 0 };
|
||||
ut64 deadline = r_time_now_mono () + (ut64)timeout * 1000;
|
||||
std::string output;
|
||||
int wstatus = 0;
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout - (tv.tv_sec * 1000)) * 1000;
|
||||
FD_ZERO (&rfds);
|
||||
FD_SET (fds[0], &rfds);
|
||||
bool complete = false;
|
||||
// keeping our copy of the write end open would suppress eof from a crashed child until the timeout expires
|
||||
close (fds[1]);
|
||||
if (select (fds[0] + 1, &rfds, NULL, NULL, &tv) > 0) {
|
||||
char ch = 0;
|
||||
if (read (fds[0], &ch, 1) != 1 || ch != 0x12) {
|
||||
R_LOG_ERROR ("Decompiler process died unexpectedly");
|
||||
while (true) {
|
||||
ut64 now = r_time_now_mono ();
|
||||
int ready = now < deadline? poll (&pfd, 1, (deadline - now + 999) / 1000): 0;
|
||||
if (ready < 0 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
eprintf ("Timeout\n");
|
||||
kill (pid, 9);
|
||||
if (ready <= 0) {
|
||||
if (!ready) {
|
||||
eprintf ("Timeout\n");
|
||||
} else {
|
||||
R_LOG_ERROR ("Cannot poll decompiler output");
|
||||
}
|
||||
break;
|
||||
}
|
||||
char buf[4096];
|
||||
ssize_t n = read (fds[0], buf, sizeof (buf));
|
||||
if (n < 0 && errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
if (n <= 0) {
|
||||
complete = n == 0;
|
||||
if (!complete) {
|
||||
R_LOG_ERROR ("Cannot read decompiler output");
|
||||
}
|
||||
break;
|
||||
}
|
||||
output.append (buf, n);
|
||||
}
|
||||
while (waitpid (pid, &wstatus, 0) == -1 && errno == EINTR) {
|
||||
if (!complete) {
|
||||
kill (pid, SIGKILL);
|
||||
}
|
||||
fflush (stderr);
|
||||
fflush (stdout);
|
||||
close (fds[0]);
|
||||
pid_t waited;
|
||||
do {
|
||||
waited = waitpid (pid, &wstatus, 0);
|
||||
} while (waited == -1 && errno == EINTR);
|
||||
if (complete && waited == pid && WIFEXITED (wstatus) && WEXITSTATUS (wstatus) == 0) {
|
||||
// Apply filters and redirections in the parent, just like a non-worker command.
|
||||
r_cons_write (core->cons, output.data (), output.size ());
|
||||
} else if (complete) {
|
||||
R_LOG_ERROR ("Decompiler process died unexpectedly");
|
||||
}
|
||||
}
|
||||
#else
|
||||
R_LOG_WARN ("r2ghidra.timeout is not supported outside UNIX systems.");
|
||||
|
||||
@@ -66,8 +66,9 @@ RUN
|
||||
|
||||
NAME=pdgj includes p-code state when decompilation uses a timeout worker
|
||||
FILE=-
|
||||
ARGS=-a x86 -b 64 -e r2ghidra.timeout=5000 -e log.level=0
|
||||
ARGS=-a x86 -b 64
|
||||
CMDS=<<EOF
|
||||
e r2ghidra.timeout=5000
|
||||
wx b82a000000c3
|
||||
af
|
||||
pdgj~{pcode_ops[0].is_dead}
|
||||
@@ -151,8 +152,9 @@ RUN
|
||||
|
||||
NAME=removed operation capture preserves full addresses through a timeout worker
|
||||
FILE=-
|
||||
ARGS=-a x86 -b 64 -m 0x20000000000001 -e r2ghidra.timeout=5000 -e log.level=0
|
||||
ARGS=-a x86 -b 64 -m 0x20000000000001
|
||||
CMDS=<<EOF
|
||||
e r2ghidra.timeout=5000
|
||||
wx b801000000b82a000000c3
|
||||
af
|
||||
e r2ghidra.deadcode=true
|
||||
|
||||
Reference in new issue
Block a user