diff options
Diffstat (limited to 'libbacktrace/backtrace_test.cpp')
-rw-r--r-- | libbacktrace/backtrace_test.cpp | 57 |
1 files changed, 14 insertions, 43 deletions
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp index 0a60ec4f3..9911e74a6 100644 --- a/libbacktrace/backtrace_test.cpp +++ b/libbacktrace/backtrace_test.cpp | |||
@@ -77,6 +77,7 @@ struct thread_t { | |||
77 | 77 | ||
78 | struct dump_thread_t { | 78 | struct dump_thread_t { |
79 | thread_t thread; | 79 | thread_t thread; |
80 | BacktraceMap* map; | ||
80 | Backtrace* backtrace; | 81 | Backtrace* backtrace; |
81 | int32_t* now; | 82 | int32_t* now; |
82 | int32_t done; | 83 | int32_t done; |
@@ -632,7 +633,7 @@ static void* ThreadDump(void* data) { | |||
632 | } | 633 | } |
633 | 634 | ||
634 | // The status of the actual unwind will be checked elsewhere. | 635 | // The status of the actual unwind will be checked elsewhere. |
635 | dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid); | 636 | dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid, dump->map); |
636 | dump->backtrace->Unwind(0); | 637 | dump->backtrace->Unwind(0); |
637 | 638 | ||
638 | android_atomic_acquire_store(1, &dump->done); | 639 | android_atomic_acquire_store(1, &dump->done); |
@@ -640,8 +641,8 @@ static void* ThreadDump(void* data) { | |||
640 | return nullptr; | 641 | return nullptr; |
641 | } | 642 | } |
642 | 643 | ||
643 | TEST(libbacktrace, thread_multiple_dump) { | 644 | static void MultipleThreadDumpTest(bool share_map) { |
644 | // Dump NUM_THREADS simultaneously. | 645 | // Dump NUM_THREADS simultaneously using the same map. |
645 | std::vector<thread_t> runners(NUM_THREADS); | 646 | std::vector<thread_t> runners(NUM_THREADS); |
646 | std::vector<dump_thread_t> dumpers(NUM_THREADS); | 647 | std::vector<dump_thread_t> dumpers(NUM_THREADS); |
647 | 648 | ||
@@ -662,12 +663,17 @@ TEST(libbacktrace, thread_multiple_dump) { | |||
662 | 663 | ||
663 | // Start all of the dumpers at once, they will spin until they are signalled | 664 | // Start all of the dumpers at once, they will spin until they are signalled |
664 | // to begin their dump run. | 665 | // to begin their dump run. |
666 | std::unique_ptr<BacktraceMap> map; | ||
667 | if (share_map) { | ||
668 | map.reset(BacktraceMap::Create(getpid())); | ||
669 | } | ||
665 | int32_t dump_now = 0; | 670 | int32_t dump_now = 0; |
666 | for (size_t i = 0; i < NUM_THREADS; i++) { | 671 | for (size_t i = 0; i < NUM_THREADS; i++) { |
667 | dumpers[i].thread.tid = runners[i].tid; | 672 | dumpers[i].thread.tid = runners[i].tid; |
668 | dumpers[i].thread.state = 0; | 673 | dumpers[i].thread.state = 0; |
669 | dumpers[i].done = 0; | 674 | dumpers[i].done = 0; |
670 | dumpers[i].now = &dump_now; | 675 | dumpers[i].now = &dump_now; |
676 | dumpers[i].map = map.get(); | ||
671 | 677 | ||
672 | ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0); | 678 | ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0); |
673 | } | 679 | } |
@@ -689,47 +695,12 @@ TEST(libbacktrace, thread_multiple_dump) { | |||
689 | } | 695 | } |
690 | } | 696 | } |
691 | 697 | ||
692 | TEST(libbacktrace, thread_multiple_dump_same_thread) { | 698 | TEST(libbacktrace, thread_multiple_dump) { |
693 | pthread_attr_t attr; | 699 | MultipleThreadDumpTest(false); |
694 | pthread_attr_init(&attr); | 700 | } |
695 | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | ||
696 | thread_t runner; | ||
697 | runner.tid = 0; | ||
698 | runner.state = 0; | ||
699 | ASSERT_TRUE(pthread_create(&runner.threadId, &attr, ThreadMaxRun, &runner) == 0); | ||
700 | |||
701 | // Wait for tids to be set. | ||
702 | ASSERT_TRUE(WaitForNonZero(&runner.state, 30)); | ||
703 | |||
704 | // Start all of the dumpers at once, they will spin until they are signalled | ||
705 | // to begin their dump run. | ||
706 | int32_t dump_now = 0; | ||
707 | // Dump the same thread NUM_THREADS simultaneously. | ||
708 | std::vector<dump_thread_t> dumpers(NUM_THREADS); | ||
709 | for (size_t i = 0; i < NUM_THREADS; i++) { | ||
710 | dumpers[i].thread.tid = runner.tid; | ||
711 | dumpers[i].thread.state = 0; | ||
712 | dumpers[i].done = 0; | ||
713 | dumpers[i].now = &dump_now; | ||
714 | |||
715 | ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0); | ||
716 | } | ||
717 | |||
718 | // Start all of the dumpers going at once. | ||
719 | android_atomic_acquire_store(1, &dump_now); | ||
720 | |||
721 | for (size_t i = 0; i < NUM_THREADS; i++) { | ||
722 | ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 30)); | ||
723 | |||
724 | ASSERT_TRUE(dumpers[i].backtrace != nullptr); | ||
725 | VerifyMaxDump(dumpers[i].backtrace); | ||
726 | |||
727 | delete dumpers[i].backtrace; | ||
728 | dumpers[i].backtrace = nullptr; | ||
729 | } | ||
730 | 701 | ||
731 | // Tell the runner thread to exit its infinite loop. | 702 | TEST(libbacktrace, thread_multiple_dump_same_map) { |
732 | android_atomic_acquire_store(0, &runner.state); | 703 | MultipleThreadDumpTest(true); |
733 | } | 704 | } |
734 | 705 | ||
735 | // This test is for UnwindMaps that should share the same map cursor when | 706 | // This test is for UnwindMaps that should share the same map cursor when |