Processes create and use kernel objects to perform work. Just as memory can be leaked or misused (e.g use-after-free), handles to kernel object can be leaked or misused (e.g use-after-close).
Handles tool
To help developers diagnose handle issues use the handles
tool, below
is a sample of process 29831 which is wlancfg.cm :
$ handles 29831
handle koid rkoid rights type
0xa8d44a0f: 29973 0x0000d0ef vmo
0xa8e44aab: 29847 29846 0x0000f00e channel
0xa8d44a0b: 29972 0x0000d0ef vmo
0xa8e42413: 9931 9930 0x0000f00e channel
0xa8d44a07: 29971 0x0000d0ef vmo
0xa8f44a1f: 29969 29970 0x0000f00e channel
0xa8a44a3b: 29964 0x0000d0ef vmo
0xa8d44a17: 29962 29963 0x0000f00e channel
0xa8844a43: 29961 0x0000d0ef vmo
0xa8f44a4b: 29960 0x0000d0ef vmo
0xa8e44a3f: 29959 0x0000d0ef vmo
0xa8e44a23: 29958 0x0000800f port
0xa8f44a2f: 29957 0x0000d0ef vmo
0xa8644a53: 29911 0x0000d0ef vmo
0xa8a44a7f: 29908 0x0000d0ef vmo
0xa8844a6b: 29907 0x0000d0ef vmo
0xa8f44a63: 29906 0x0000d0ef vmo
0xa8844a6f: 29905 0x0000d0ef vmo
0xa8f44a8b: 29904 0x0000d0ef vmo
0xa8944a9f: 29903 0x0000d0ef vmo
0xa8444a83: 29900 0x0000800f vmar
0xa8e44a77: 29845 0x0000d0ef vmo
0xa8f44a8f: 1034 0x0000d0f7 vmo
0xa8d44aa3: 1129 0x0000d00b log
0xa8d44abf: 1129 0x0000d00b log
0xa8d44abb: 1129 0x0000d00b log
0xa8644aef: 29827 29828 0x0000f00e channel
0xa8844ac3: 29826 8711 0x0007dfcf job
0xa8144afb: 29825 29824 0x0000f00e channel
0xa8e44adb: 29816 29817 0x0000f00e channel
0xa8e44ad3: 29776 29777 0x0000f00e channel
0xa894496b: 29766 29767 0x0000f00e channel
0xa8d44a97: 29833 29831 0x0004d2cf thread
0xa8d44a93: 29832 0x0000801f vmar
0xa8d44aaf: 29831 29826 0x0006d3cf process
0xa8f44a73: 29850 0x0000d00b log
0xa8f44af3: 29768 29769 0x0000f00e channel
0xa8e44aa7: 29834 29835 0x0000f00e channel
38 handles
The handles <pid>
tool dumps the process handle table, which holds all
accessible handles for that particular process at the moment of invocation.
For each handle the tool prints the handle value, the koid of the object it points to, the related koid (rkoid) if the object has a related object, the rights of the handle and the type of object.
In the example above, it shows 38 unique handles, which map to 36 unique objects; 3 of the handles point to the same "log" object with koid 1129.
It should be noted that not all alive objects might be displayed by the tool. For example, a thread can be alive even if there are not handles open to it and VMOs can be held alive by the associated VMAR.
The handles
tool supports filtering and reverse filtering by object type; use
handles --help
to see all the options.
Handles in the debugger
You can view handle information using the debugger.
To do this, attach to the process in question and run the handles
command. This shows the handle
value, object type, and object koid:
[zxdb] handles
504103211 ZX_OBJ_TYPE_VMO 27851
504103271 ZX_OBJ_TYPE_VMO 27719
505151859 ZX_OBJ_TYPE_VMO 27720
505151867 ZX_OBJ_TYPE_VMO 27718
506200511 ZX_OBJ_TYPE_PORT 27976
507249163 ZX_OBJ_TYPE_VMAR 27716
508297363 ZX_OBJ_TYPE_VMO 28200
508297379 ZX_OBJ_TYPE_VMO 28187
508297387 ZX_OBJ_TYPE_SOCKET 28189
508297731 ZX_OBJ_TYPE_CLOCK 1263
508297735 ZX_OBJ_TYPE_LOG 1275
508297755 ZX_OBJ_TYPE_LOG 1275
You can also view basic information about a handle by calling handle
and specifying a handle
value:
[zxdb] handle 508302371
Type ZX_OBJ_TYPE_CHANNEL
Value 508302371
Rights ZX_RIGHT_TRANSFER
ZX_RIGHT_READ
ZX_RIGHT_WRITE
ZX_RIGHT_SIGNAL
ZX_RIGHT_SIGNAL_PEER
ZX_RIGHT_WAIT
ZX_RIGHT_INSPECT
Koid 31062
Related koid 31061
If the object referenced by the handle is related to another object (such as the other end of a
channel, or the parent of a job) then related_koid
is the koid of that other object. If there is
no other related object, this value is zero. In this example, the related koid is the other end of
the channel. This relationship is immutable: an object's related_koid
does not change even if the
related object no longer exists.
Bad handle policy
Using a handle after it has been closed or closing a handle that has been already closed are mistakes that can create hard to diagnose errors.
In order to help developers find these issues, the "bad handle" Job policy can be activated using zx_job_set_policy with the condition ZX_POL_BAD_HANDLE and the action ZX_POL_ACTION_ALLOW_EXCEPTION. When a process is launched under a job with this policy, any use of an already closed handle will generate an exception that if not handled will terminate the process and log the offending call stack or that can be trapped by the debugger for interactive troubleshooting.