Browse Source

failtest: detect leaks in children.

If we need to clean up the children, they didn't exit cleanly.

This takes a bit more care when writing tests, but found a leak in tdb2.
Rusty Russell 15 years ago
parent
commit
460f62ce63
2 changed files with 23 additions and 12 deletions
  1. 15 8
      ccan/failtest/failtest.c
  2. 8 4
      ccan/failtest/test/run-write.c

+ 15 - 8
ccan/failtest/failtest.c

@@ -317,21 +317,28 @@ static NORETURN void failtest_cleanup(bool forced_cleanup, int status)
 {
 	int i;
 
+	/* For children, we don't care if they "failed" the testing. */
+	if (control_fd != -1)
+		status = 0;
+
 	if (forced_cleanup)
 		history_num--;
 
 	/* Cleanup everything, in reverse order. */
-	for (i = history_num - 1; i >= 0; i--)
-		if (history[i].cleanup)
-			history[i].cleanup(&history[i].u);
+	for (i = history_num - 1; i >= 0; i--) {
+		if (!history[i].cleanup)
+			continue;
+		if (!forced_cleanup) {
+			printf("Leak at %s:%u\n",
+			       history[i].file, history[i].line);
+			status = 1;
+		}
+		history[i].cleanup(&history[i].u);
+	}
 
 	free_everything();
-
-	if (control_fd == -1)
-		exit(status);
-
 	tell_parent(SUCCESS);
-	exit(0);
+	exit(status);
 }
 
 static bool should_fail(struct failtest_call *call)

+ 8 - 4
ccan/failtest/test/run-write.c

@@ -7,15 +7,16 @@
 /* Include the C files directly. */
 #include <ccan/failtest/failtest.c>
 
-int main(void)
+int main(int argc, char *argv[])
 {
 	int fd;
 	char *p;
 	char buf[] = "Hello world!";
 
 	plan_tests(5);
+	failtest_init(argc, argv);
 
-	fd = failtest_open("run-write-scratchpad", "run-write.c", 1,
+	fd = failtest_open("run-write-scratchpad", __FILE__, __LINE__,
 			   O_RDWR|O_CREAT, 0600);
 	/* Child will fail, ignore. */
 	if (fd < 0)
@@ -23,14 +24,16 @@ int main(void)
 	write(fd, buf, strlen(buf));
 	ok1(lseek(fd, 0, SEEK_CUR) == strlen(buf));
 
-	p = failtest_malloc(100, "run-write.c", 1);
+	p = failtest_malloc(100, __FILE__, __LINE__);
 	if (!p) {
 		/* We are the child.  Do a heap of writes. */
 		unsigned int i;
 
 		for (i = 0; i < strlen(buf)+1; i++)
-			if (failtest_write(fd, "x", 1, "run-write.c", 1) == 1)
+			if (failtest_write(fd, "x", 1, __FILE__, __LINE__)
+			    == 1)
 				break;
+		failtest_close(fd, __FILE__, __LINE__);
 		failtest_exit(0);
 	}
 
@@ -41,6 +44,7 @@ int main(void)
 	lseek(fd, 0, SEEK_SET);
 	ok1(read(fd, buf, strlen(buf)) == strlen("Hello world!"));
 	ok1(strcmp(buf, "Hello world!") == 0);
+	failtest_close(fd, __FILE__, __LINE__);
 
 	return exit_status();
 }