summaryrefslogtreecommitdiffstats
path: root/libbacktrace/backtrace_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbacktrace/backtrace_test.c')
-rw-r--r--libbacktrace/backtrace_test.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/libbacktrace/backtrace_test.c b/libbacktrace/backtrace_test.c
index 34d3519..6155c9b 100644
--- a/libbacktrace/backtrace_test.c
+++ b/libbacktrace/backtrace_test.c
@@ -22,6 +22,7 @@
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
+#include <errno.h>
#include <unistd.h>
#include <inttypes.h>
@@ -29,6 +30,8 @@
#define FINISH(pid) dump_frames(&backtrace); if (pid < 0) exit(1); else return false;
+#define WAIT_INTERVAL_USECS 1000
+
// Prototypes for functions in the test library.
int test_level_one(int, int, int, int, bool (*)(pid_t));
@@ -52,6 +55,21 @@ void dump_frames(const backtrace_t* backtrace) {
}
}
+void wait_for_stop(pid_t pid, size_t max_usecs_to_wait) {
+ siginfo_t si;
+ size_t usecs_waited = 0;
+
+ while (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) < 0 && (errno == EINTR || errno == ESRCH)) {
+ if (usecs_waited >= max_usecs_to_wait) {
+ printf("The process did not get to a stopping point in %zu usecs.\n",
+ usecs_waited);
+ break;
+ }
+ usleep(WAIT_INTERVAL_USECS);
+ usecs_waited += WAIT_INTERVAL_USECS;
+ }
+}
+
bool check_frame(const backtrace_t* backtrace, size_t frame_num,
const char* expected_name) {
if (backtrace->frames[frame_num].proc_name == NULL) {
@@ -153,6 +171,10 @@ void verify_proc_test(pid_t pid, bool (*verify_func)(pid_t)) {
kill(pid, SIGKILL);
exit(1);
}
+
+ // Wait up to 1 second for the process to get to a point that we can trace it.
+ wait_for_stop(pid, 1000000);
+
bool pass = verify_func(pid);
if (ptrace(PTRACE_DETACH, pid, 0, 0) != 0) {
printf("Failed to detach from pid %d\n", pid);