diff options
Diffstat (limited to 'lib/Plugins/CCpp.cpp')
-rw-r--r-- | lib/Plugins/CCpp.cpp | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index fb209bc5..544d3ef6 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -137,12 +137,37 @@ static int ExecVP(char **pArgs, uid_t uid, int redirect_stderr, string& pOutput) int pipeout[2]; pid_t child = fork_execv_on_steroids(flags, pArgs, pipeout, (char**)unsetenv_vec, /*dir:*/ NULL, uid); - int r; - char buff[1024]; - while ((r = read(pipeout[0], buff, sizeof(buff) - 1)) > 0) + /* We use this function to run gdb and unstrip. Bugs in gdb or corrupted + * coredumps were observed to cause gdb to enter infinite loop. + * Therefore we have a (largish) timeout, after which we kill the child. + */ + int t = time(NULL); /* int is enough, no need to use time_t */ + int endtime = t + 60; + while (1) { + int timeout = endtime - t; + if (timeout < 0) + { + kill(child, SIGKILL); + pOutput += "\nTimeout exceeded: 60 second, killing "; + pOutput += pArgs[0]; + pOutput += "\n"; + break; + } + + /* We don't check poll result - checking read result is enough */ + struct pollfd pfd; + pfd.fd = pipeout[0]; + pfd.events = POLLIN; + poll(&pfd, 1, timeout * 1000); + + char buff[1024]; + int r = read(pipeout[0], buff, sizeof(buff) - 1); + if (r <= 0) + break; buff[r] = '\0'; pOutput += buff; + t = time(NULL); } close(pipeout[0]); |