Crashlog: Use a temp file instead of a pipe to read from gdb/lldb
This commit is contained in:
@@ -48,23 +48,35 @@
|
|||||||
#define MAX_STACK_FRAMES 64
|
#define MAX_STACK_FRAMES 64
|
||||||
|
|
||||||
#if !defined(WITHOUT_DBG_LLDB)
|
#if !defined(WITHOUT_DBG_LLDB)
|
||||||
static bool ExecReadStdout(const char *file, char *const *args, char *&buffer, const char *last)
|
static bool ExecReadStdoutThroughFile(const char *file, char *const *args, char *&buffer, const char *last)
|
||||||
{
|
{
|
||||||
int null_fd = open("/dev/null", O_RDWR);
|
int null_fd = open("/dev/null", O_RDWR);
|
||||||
if (null_fd == -1) return false;
|
if (null_fd == -1) return false;
|
||||||
|
|
||||||
int pipefd[2];
|
char name[MAX_PATH];
|
||||||
if (pipe(pipefd) == -1) return false;
|
extern std::string _personal_dir;
|
||||||
|
seprintf(name, lastof(name), "%sopenttd-tmp-XXXXXX", _personal_dir.c_str());
|
||||||
|
int fd = mkstemp(name);
|
||||||
|
if (fd == -1) {
|
||||||
|
close(null_fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlink file but leave fd open until finished with */
|
||||||
|
unlink(name);
|
||||||
|
|
||||||
int pid = fork();
|
int pid = fork();
|
||||||
if (pid < 0) return false;
|
if (pid < 0) {
|
||||||
|
close(null_fd);
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
/* child */
|
/* child */
|
||||||
|
|
||||||
close(pipefd[0]); /* Close unused read end */
|
dup2(fd, STDOUT_FILENO);
|
||||||
dup2(pipefd[1], STDOUT_FILENO);
|
close(fd);
|
||||||
close(pipefd[1]);
|
|
||||||
dup2(null_fd, STDERR_FILENO);
|
dup2(null_fd, STDERR_FILENO);
|
||||||
dup2(null_fd, STDIN_FILENO);
|
dup2(null_fd, STDIN_FILENO);
|
||||||
close(null_fd);
|
close(null_fd);
|
||||||
@@ -76,10 +88,18 @@ static bool ExecReadStdout(const char *file, char *const *args, char *&buffer, c
|
|||||||
/* parent */
|
/* parent */
|
||||||
|
|
||||||
close(null_fd);
|
close(null_fd);
|
||||||
close(pipefd[1]); /* Close unused write end */
|
|
||||||
|
|
||||||
|
int status;
|
||||||
|
int wait_ret = waitpid(pid, &status, 0);
|
||||||
|
if (wait_ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||||
|
/* command did not appear to run successfully */
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
/* command executed successfully */
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
while (buffer < last) {
|
while (buffer < last) {
|
||||||
ssize_t res = read(pipefd[0], buffer, last - buffer);
|
ssize_t res = read(fd, buffer, last - buffer);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
if (errno == EINTR) continue;
|
if (errno == EINTR) continue;
|
||||||
break;
|
break;
|
||||||
@@ -90,16 +110,7 @@ static bool ExecReadStdout(const char *file, char *const *args, char *&buffer, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
buffer += seprintf(buffer, last, "\n");
|
buffer += seprintf(buffer, last, "\n");
|
||||||
|
close(fd);
|
||||||
close(pipefd[0]); /* close read end */
|
|
||||||
|
|
||||||
int status;
|
|
||||||
int wait_ret = waitpid(pid, &status, 0);
|
|
||||||
if (wait_ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
|
||||||
/* command did not appear to run successfully */
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
/* command executed successfully */
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,7 +295,7 @@ class CrashLogOSX : public CrashLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
args.push_back(nullptr);
|
args.push_back(nullptr);
|
||||||
if (!ExecReadStdout("lldb", const_cast<char* const*>(&(args[0])), buffer, last)) {
|
if (!ExecReadStdoutThroughFile("lldb", const_cast<char* const*>(&(args[0])), buffer, last)) {
|
||||||
buffer = buffer_orig;
|
buffer = buffer_orig;
|
||||||
}
|
}
|
||||||
#endif /* !WITHOUT_DBG_LLDB */
|
#endif /* !WITHOUT_DBG_LLDB */
|
||||||
|
@@ -128,6 +128,73 @@ static bool ExecReadStdout(const char *file, char *const *args, char *&buffer, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ExecReadStdoutThroughFile(const char *file, char *const *args, char *&buffer, const char *last)
|
||||||
|
{
|
||||||
|
int null_fd = open("/dev/null", O_RDWR);
|
||||||
|
if (null_fd == -1) return false;
|
||||||
|
|
||||||
|
char name[MAX_PATH];
|
||||||
|
extern std::string _personal_dir;
|
||||||
|
seprintf(name, lastof(name), "%sopenttd-tmp-XXXXXX", _personal_dir.c_str());
|
||||||
|
int fd = mkstemp(name);
|
||||||
|
if (fd == -1) {
|
||||||
|
close(null_fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlink file but leave fd open until finished with */
|
||||||
|
unlink(name);
|
||||||
|
|
||||||
|
int pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
close(null_fd);
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid == 0) {
|
||||||
|
/* child */
|
||||||
|
|
||||||
|
dup2(fd, STDOUT_FILENO);
|
||||||
|
close(fd);
|
||||||
|
dup2(null_fd, STDERR_FILENO);
|
||||||
|
dup2(null_fd, STDIN_FILENO);
|
||||||
|
close(null_fd);
|
||||||
|
|
||||||
|
execvp(file, args);
|
||||||
|
exit(42);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parent */
|
||||||
|
|
||||||
|
close(null_fd);
|
||||||
|
|
||||||
|
int status;
|
||||||
|
int wait_ret = waitpid(pid, &status, 0);
|
||||||
|
if (wait_ret == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||||
|
/* command did not appear to run successfully */
|
||||||
|
close(fd);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
/* command executed successfully */
|
||||||
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
while (buffer < last) {
|
||||||
|
ssize_t res = read(fd, buffer, last - buffer);
|
||||||
|
if (res < 0) {
|
||||||
|
if (errno == EINTR) continue;
|
||||||
|
break;
|
||||||
|
} else if (res == 0) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
buffer += res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer += seprintf(buffer, last, "\n");
|
||||||
|
close(fd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unix implementation for the crash logger.
|
* Unix implementation for the crash logger.
|
||||||
*/
|
*/
|
||||||
@@ -357,7 +424,7 @@ class CrashLogUnix : public CrashLog {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
args.push_back(nullptr);
|
args.push_back(nullptr);
|
||||||
if (!ExecReadStdout("gdb", const_cast<char* const*>(&(args[0])), buffer, last)) {
|
if (!ExecReadStdoutThroughFile("gdb", const_cast<char* const*>(&(args[0])), buffer, last)) {
|
||||||
buffer = buffer_orig;
|
buffer = buffer_orig;
|
||||||
}
|
}
|
||||||
#endif /* WITH_DBG_GDB */
|
#endif /* WITH_DBG_GDB */
|
||||||
|
Reference in New Issue
Block a user