From 34deb963ec12ea2375449e978ab28e6f13a01072 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 3 Jun 2010 15:52:43 +0200 Subject: CCpp analyzer: add 60 sec cap on gdb run time. I tested gdb on LARGE coredump (openoffice) and it takes about 5 seconds to process it. 60 seconds should be more than plenty. Signed-off-by: Denys Vlasenko --- lib/Plugins/CCpp.cpp | 31 ++++++++++++++++++++++++++++--- 1 file 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]); -- cgit