blob: c9a0fcae66b13e637dc09e8fef6580b8afce18a2 [file] [log] [blame]
// Copyright 2018 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.
#ifndef GARNET_LIB_DEBUGGER_UTILS_JOBS_H_
#define GARNET_LIB_DEBUGGER_UTILS_JOBS_H_
#include <functional>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/thread.h>
namespace debugger_utils {
zx::job GetDefaultJob();
using JobTreeJobCallback = std::function<zx_status_t(
zx::job* job, zx_koid_t koid, zx_koid_t parent_koid, int depth)>;
using JobTreeProcessCallback = std::function<zx_status_t(
zx::process* process, zx_koid_t koid, zx_koid_t parent_koid, int depth)>;
using JobTreeThreadCallback = std::function<zx_status_t(
zx::thread* thread, zx_koid_t koid, zx_koid_t parent_koid, int depth)>;
// Walk the job tree of |job|, beginning at |job| and descending to all its
// children. Jobs are searched in depth-first order.
// The initial |job| argument of WalkJobTree() is not consumed, however a
// callback may consume it (see below).
//
// A pointer to the zx::task object (job,process,thread) is passed to each
// callback. If the callback wishes to take over ownership of the handle it
// can do so with task->release(), with one caveat for job and process handles:
// Even though the handle is now owned by the callback, it is loaned to
// WalkJobTree, and the callback must not close/replace/transfer/whatever the
// handle until WalkJobTree returns.
// All other handles obtained during the walk are automagically closed by the
// time WalkJobTree() returns.
//
// The walk continues until either of the following happens:
// 1) Any callback returns something other than ZX_OK.
// By convention if tree walking has successfully completed and you want to
// "early exit" then return ZX_ERR_STOP from a callback.
// 2) |job_callback| has taken ownership of the |zx::job| object.
// Processes of the job and their threads are still walked, but no further
// jobs are walked, and ZX_ERR_STOP is returned.
// Remember the job handle must remain open until WalkJobTree() returns.
//
// TODO(dje): Maybe allow a callback to take ownership of a job handle and
// still continue walking of further jobs (maintaining the restriction that
// the caller can't close the handle until WalkJobTree() returns).
zx_status_t WalkJobTree(zx::job* job, JobTreeJobCallback* job_callback,
JobTreeProcessCallback* process_callback,
JobTreeThreadCallback* thread_callback);
// Simple wrapper on WalkJobTree for finding processes.
// Returns zx::process(ZX_HANDLE_INVALID) if not found.
zx::process FindProcess(zx::job* job, zx_koid_t pid);
zx::process FindProcess(zx_handle_t job, zx_koid_t pid);
} // namespace debugger_utils
#endif // GARNET_LIB_DEBUGGER_UTILS_JOBS_H_