225 lines
5.4 KiB
Groff
225 lines
5.4 KiB
Groff
.\" Copyright (c) 2021, Apple Inc. All rights reserved.
|
|
.
|
|
.Dd June 30, 2021
|
|
.Dt BACKTRACE 9
|
|
.Os Darwin
|
|
.
|
|
.Sh NAME
|
|
.Nm backtrace ,
|
|
.Nm backtrace_packed ,
|
|
.Nm backtrace_user ,
|
|
.Nd gather the PC and return addresses of a thread's kernel or user call stack
|
|
.
|
|
.Sh SYNOPSIS
|
|
.In kern/backtrace.h
|
|
.Ft unsigned int
|
|
.Fo backtrace
|
|
.Fa "uintptr_t *bt"
|
|
.Fa "unsigned int btlen"
|
|
.Fa "struct backtrace_control *ctl"
|
|
.Fa "backtrace_info_t *info_out"
|
|
.Fc
|
|
.
|
|
.Ft size_t
|
|
.Fo backtrace_packed
|
|
.Fa "backtrace_pack_t packing"
|
|
.Fa "uintptr_t *bt"
|
|
.Fa "size_t btlen"
|
|
.Fa "struct backtrace_control *ctl"
|
|
.Fa "backtrace_info_t *info_out"
|
|
.Fc
|
|
.
|
|
.Ft unsigned int
|
|
.Fo backtrace_user
|
|
.Fa "uintptr_t *bt"
|
|
.Fa "unsigned int btlen"
|
|
.Fa "struct backtrace_control *ctl"
|
|
.Fa "struct backtrace_user_info *info_out"
|
|
.Fc
|
|
.
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm backtrace ,
|
|
.Nm backtrace_packed ,
|
|
and
|
|
.Nm backtrace_user
|
|
functions fill a buffer with the current PC and return addresses of a thread's
|
|
kernel and user call stack, respectively.
|
|
This is only possible when frame pointers are pushed to the stack, alongside the
|
|
return addresses.
|
|
.Xr clang 1 ,
|
|
disables this behavior with the
|
|
.Fl fomit-frame-pointer
|
|
flag, so it will prevent these functions from working.
|
|
Furthermore, leaf functions and inlined function calls can also prevent
|
|
backtracing from reporting the source-level function control flow.
|
|
.Fn backtrace_user
|
|
operates on user call stacks, while
|
|
.Fn backtrace
|
|
captures the current kernel call stack.
|
|
.Fn backtrace_packed
|
|
writes a more compact representation of the return addresses to a buffer, which
|
|
can be unpacked with
|
|
.Xr backtrace_unpack 9 .
|
|
Calling
|
|
.Fn backtrace_user
|
|
on a kernel thread
|
|
.Pq which lacks a user context
|
|
is undefined.
|
|
.Pp
|
|
Up to
|
|
.Fa btlen
|
|
instruction addresses
|
|
.Po
|
|
or
|
|
.Fa btsize
|
|
bytes for
|
|
.Fn backtrace_packed
|
|
.Pc
|
|
are written to the buffer at
|
|
.Fa bt .
|
|
These functions also accept
|
|
.Fa ctl
|
|
and
|
|
.Fa info_out
|
|
arguments, described in
|
|
.Sx BACKTRACE_CONTROL
|
|
and
|
|
.Sx BACKTRACE_INFO ,
|
|
respectively.
|
|
.Fn backtrace_packed
|
|
takes a
|
|
.Ft backtrace_pack_t
|
|
to control which packing scheme to use.
|
|
.Pp
|
|
.Fn backtrace
|
|
records the kernel PC and call stack of the current thread.
|
|
.Pp
|
|
.Fn backtrace_packed
|
|
records the kernel PC and call stack of the current thread in a buffer in a
|
|
compact representation.
|
|
See
|
|
.Xr backtrace_pack 9
|
|
for a description of the supported formats.
|
|
.Pp
|
|
.Fn backtrace_user
|
|
records the user PC and call stack of the current thread, which must be
|
|
associated with a user space task.
|
|
.
|
|
.Sh RETURN VALUES
|
|
The
|
|
.Nm
|
|
functions return the number of PC and return address elements
|
|
.Po
|
|
or bytes for
|
|
.Fn backtrace_packed
|
|
.Pc
|
|
written to the provided buffer.
|
|
If there is space, the buffer is terminated with a NULL entry
|
|
.Po
|
|
except for
|
|
.Fn backtrace_packed
|
|
.Pc .
|
|
The
|
|
.Fa info_out
|
|
argument will be set with information about the provided call stack.
|
|
.Fn backtrace_user
|
|
will set
|
|
.Ft btui_error
|
|
to an error of the
|
|
.Xr copyin 9
|
|
routine if an error occurred during call stack traversal.
|
|
.
|
|
.Sh BACKTRACE_CONTROL
|
|
The
|
|
.Nm
|
|
functions accept a
|
|
.Ft struct backtrace_control
|
|
control argument to alter their behavior,
|
|
with the following fields:
|
|
.Bl -tag -width btc_user_thread
|
|
.It Ft btc_flags
|
|
These flags control the backtracer's behavior:
|
|
.Bl -tag -width BTF_KERN_INTERRUPTED
|
|
.It Dv BTF_KERN_INTERRUPTED
|
|
For
|
|
.Fn backtrace
|
|
only, record the PC and return addresses of the interrupted call stack.
|
|
.El
|
|
.It Ft btc_frame_addr
|
|
Start backtracing from the provided frame address.
|
|
.It Ft btc_user_thread
|
|
Capture the backtrace of the provided thread pointer.
|
|
This must be either the current thread or a different thread that is suspended
|
|
and unable to run in user space.
|
|
.It Ft btc_user_copy
|
|
For
|
|
.Fn backtrace_user
|
|
only, the function to use instead of
|
|
.Xr copyin 9
|
|
to copy data from the thread's user space virtual address space into the kernel.
|
|
.It Ft btc_user_copy_context
|
|
Additional data that's passed to the custom copy routine to act as private
|
|
context.
|
|
.El
|
|
.
|
|
.Sh BACKTRACE_INFO
|
|
The
|
|
.Nm
|
|
functions report additional information through a
|
|
.Ft backtrace_info_t
|
|
flags out-parameter,
|
|
with the following options:
|
|
.Bl -tag -width BTI_TRUNCATED
|
|
.It Dv BTI_64_BIT
|
|
The PC and call stack return addresses are 64-bit quantities.
|
|
.It Dv BTI_TRUNCATED
|
|
The backtrace has been truncated and does not terminate with the base frame.
|
|
.El
|
|
.Pp
|
|
The
|
|
.Fn backtrace_user
|
|
variant uses an out-parameter structure
|
|
.Ft struct backtrace_user_info
|
|
to return additional context:
|
|
.Bl -tag -width btui_
|
|
.It Ft btui_info
|
|
The
|
|
.Ft backtrace_info_t
|
|
flags, described above.
|
|
.It Ft btui_error
|
|
Any error encountered while copying data.
|
|
.It Ft btui_async_start_index
|
|
For Swift continuations
|
|
.Pq async stacks ,
|
|
the location where the continuation hint was found and where it logically
|
|
branches from the standard call stack.
|
|
.It Ft btui_async_frame_addr
|
|
The frame address of the Swift continuation to pass in to a subsequent call
|
|
to
|
|
.Fn backtrace_user
|
|
.Pq as the control structure's frame address field
|
|
to follow the corresponding async stack.
|
|
.It Ft btui_next_frame_addr
|
|
In the case of a truncated backtrace due to lack of space in the destination
|
|
buffer, the next frame address to resume the backtrace operation.
|
|
.El
|
|
.
|
|
.Sh EXAMPLE
|
|
.Bd -literal
|
|
uintptr_t bt[8] = {};
|
|
enum backtrace_info bti = BTI_NONE;
|
|
unsigned int len = backtrace(bt, sizeof(bt) / sizeof(bt[0]), NULL, &bti);
|
|
for (unsigned int i = 0; i < len; i++) {
|
|
printf("%d: 0x%lx\\n", i, bt[i]);
|
|
}
|
|
if (bti & BTI_TRUNCATED) {
|
|
printf("[... TRUNCATED ...]\\n");
|
|
}
|
|
.Ed
|
|
.
|
|
.Sh SEE ALSO
|
|
.Xr backtrace 3 ,
|
|
.Xr backtrace_pack 9 ,
|
|
and
|
|
.Xr copyin 9
|