unsigned int failtest_timeout_ms = 20000;
const char *failpath;
+const char *debugpath;
enum info_type {
WRITE,
}
}
+ /* Attach debugger if they asked for it. */
+ if (debugpath && history_num == strlen(debugpath)) {
+ unsigned int i;
+
+ for (i = 0; i < history_num; i++) {
+ char c = info_to_arg[history[i].type];
+ if (history[i].fail)
+ c = toupper(c);
+ if (c != debugpath[i])
+ break;
+ }
+ if (i == history_num) {
+ char str[80];
+
+ /* Don't timeout. */
+ signal(SIGUSR1, SIG_IGN);
+ sprintf(str, "xterm -e gdb /proc/%d/exe %d &",
+ getpid(), getpid());
+ system(str);
+ sleep(5);
+ }
+ }
+
if (!failtest_hook(history, history_num)) {
call->fail = false;
return false;
close(output[0]);
close(control[0]);
waitpid(child, &status, 0);
- if (!WIFEXITED(status))
- child_fail(out, outlen, "Killed by signal %u: ",
- WTERMSIG(status));
+ if (!WIFEXITED(status)) {
+ if (WTERMSIG(status) == SIGUSR1)
+ child_fail(out, outlen, "Timed out");
+ else
+ child_fail(out, outlen, "Killed by signal %u: ",
+ WTERMSIG(status));
+ }
/* Child printed failure already, just pass up exit code. */
if (type == FAILURE) {
fprintf(stderr, "%.*s", (int)outlen, out);
/* Avoid memory leak! */
if (p == &unrecorded_call)
free((char *)call.pathname);
- if (should_fail(p)) {
+ p->u.open.ret = open(pathname, call.flags, call.mode);
+
+ if (!failpath && p->u.open.ret == -1) {
+ p->fail = false;
+ p->error = errno;
+ } else if (should_fail(p)) {
+ close(p->u.open.ret);
p->u.open.ret = -1;
/* FIXME: Play with error codes? */
p->error = EACCES;
} else {
- p->u.open.ret = open(pathname, call.flags, call.mode);
set_cleanup(p, cleanup_open, struct open_call);
}
errno = p->error;
} else if (strcmp(argv[i], "--tracepath") == 0) {
tracefd = dup(STDERR_FILENO);
failtest_timeout_ms = -1;
+ } else if (!strncmp(argv[i], "--debugpath=",
+ strlen("--debugpath="))) {
+ debugpath = argv[i] + strlen("--debugpath=");
}
}
gettimeofday(&start, NULL);
{
int i;
- if (control_fd == -1) {
- free_everything();
- exit(status);
- }
-
if (failtest_exit_check) {
if (!failtest_exit_check(history, history_num))
child_fail(NULL, 0, "failtest_exit_check failed\n");
}
+ if (control_fd == -1) {
+ free_everything();
+ exit(status);
+ }
+
/* Cleanup everything, in reverse order. */
for (i = history_num - 1; i >= 0; i--)
if (history[i].cleanup)