| // Copyright 2019 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. | |
| #include <lib/backtrace-request/backtrace-request.h> | |
| #include <lib/zx/event.h> | |
| #include <stdio.h> | |
| #include <thread> | |
| // Program that sets up a number on thread at the cusp of some recursive calls and then calls a | |
| // backtrace request in order to get all of them printed. | |
| namespace { | |
| // |from_event| is used from the creator to make this thread wait before finishing. | |
| // |to_event| is an event this thread triggers when it is at the top frame of the recursive calls. | |
| void SomeDeepStack(const zx::event* from_event, const zx::event* to_event, int id, int count) { | |
| if (count > 0) { | |
| SomeDeepStack(from_event, to_event, id, count - 1); | |
| return; | |
| } | |
| to_event->signal(0, ZX_USER_SIGNAL_0); | |
| from_event->wait_one(ZX_USER_SIGNAL_0, zx::time::infinite(), nullptr); | |
| // Create the backtrace request. | |
| printf("Thread %d done.\n", id); | |
| } | |
| constexpr int kThreadCount = 4; | |
| zx::event CreateEvent() { | |
| zx::event event; | |
| zx::event::create(0, &event); | |
| return event; | |
| } | |
| } // namespace | |
| int main() { | |
| zx::event wait_event = CreateEvent(); | |
| zx::event events[kThreadCount]; | |
| for (auto& event : events) { | |
| event = CreateEvent(); | |
| } | |
| // Create all the threads. | |
| std::thread threads[kThreadCount]; | |
| for (int i = 0; i < kThreadCount; i++) { | |
| threads[i] = std::thread(SomeDeepStack, &wait_event, &events[i], i, i); | |
| } | |
| // Wait for all of them to reach the end of the stack. | |
| for (int i = 0; i < kThreadCount; i++) { | |
| events[i].wait_one(ZX_USER_SIGNAL_0, zx::time::infinite(), nullptr); | |
| printf("Thread %d is ready.\n", i); | |
| } | |
| // Create the backtrace request. | |
| printf("Doing backtrace request.\n"); | |
| backtrace_request(); | |
| // Tell all the threads to finish and join them. | |
| wait_event.signal(0, ZX_USER_SIGNAL_0); | |
| for (auto& thread : threads) { | |
| thread.join(); | |
| } | |
| printf("Done doing backtrace request.\n"); | |
| } |