xref: /xnu-10063.121.3/doc/debugging/task_ref.md (revision 2c2f96dc2b9a4408a43d3150ae9c105355ca3daa)
1*2c2f96dcSApple OSS DistributionsTask References
2*2c2f96dcSApple OSS Distributions===============
3*2c2f96dcSApple OSS Distributions
4*2c2f96dcSApple OSS DistributionsFinding the source of task reference count leaks.
5*2c2f96dcSApple OSS Distributions
6*2c2f96dcSApple OSS DistributionsBackground
7*2c2f96dcSApple OSS Distributions----------
8*2c2f96dcSApple OSS Distributions
9*2c2f96dcSApple OSS DistributionsTasks in XNU are reference counted. When a task is created it starts with two
10*2c2f96dcSApple OSS Distributionsreferences - one for the caller and one for the task itself. Over the lifetime
11*2c2f96dcSApple OSS Distributionsof the task this reference count is modified, for example when a thread is
12*2c2f96dcSApple OSS Distributionscreated it increments the reference count and when it exits that count drops.
13*2c2f96dcSApple OSS DistributionsWhen a reference count reaches zero, the task is freed.
14*2c2f96dcSApple OSS Distributions
15*2c2f96dcSApple OSS DistributionsTo grab a reference:
16*2c2f96dcSApple OSS Distributions```c
17*2c2f96dcSApple OSS Distributionstask_reference()
18*2c2f96dcSApple OSS Distributions```
19*2c2f96dcSApple OSS Distributions
20*2c2f96dcSApple OSS DistributionsTo release a reference:
21*2c2f96dcSApple OSS Distributions```c
22*2c2f96dcSApple OSS Distributionstask_deallocate()
23*2c2f96dcSApple OSS Distributions```
24*2c2f96dcSApple OSS Distributions
25*2c2f96dcSApple OSS DistributionsOne of the big problems seen with task references is that difficult to debug
26*2c2f96dcSApple OSS Distributions_leaks_ commonly occur. This happens when a reference is taken but never
27*2c2f96dcSApple OSS Distributionsreleased. The task is kept around indefinitely and eventually the system runs
28*2c2f96dcSApple OSS Distributionsout of a finite resource (for example ASIDs). At this point there is very little
29*2c2f96dcSApple OSS Distributionsinformation to determine what code was responsible for the leak.
30*2c2f96dcSApple OSS Distributions
31*2c2f96dcSApple OSS Distributions
32*2c2f96dcSApple OSS DistributionsTask Reference Groups
33*2c2f96dcSApple OSS Distributions--------------------
34*2c2f96dcSApple OSS Distributions
35*2c2f96dcSApple OSS DistributionsReference groups are a feature which keep track of statistics (and when
36*2c2f96dcSApple OSS Distributionsconfigured backtrace information) for a set of references. Reference groups are
37*2c2f96dcSApple OSS Distributionshierarchical. To help with debugging the following task reference group
38*2c2f96dcSApple OSS Distributionshierarchy is used:
39*2c2f96dcSApple OSS Distributions
40*2c2f96dcSApple OSS Distributions```
41*2c2f96dcSApple OSS Distributionstask
42*2c2f96dcSApple OSS Distributions   -> task_internal
43*2c2f96dcSApple OSS Distributions      -> task_local_internal
44*2c2f96dcSApple OSS Distributions   -> task_kernel
45*2c2f96dcSApple OSS Distributions      -> task_local_internal
46*2c2f96dcSApple OSS Distributions   -> task_mig
47*2c2f96dcSApple OSS Distributions      -> task_local_internal
48*2c2f96dcSApple OSS Distributions   -> task_external
49*2c2f96dcSApple OSS Distributions      -> task_local_external
50*2c2f96dcSApple OSS Distributions      -> task_com.apple.security.sandbox
51*2c2f96dcSApple OSS Distributions          -> task_com.apple.security.sandbox
52*2c2f96dcSApple OSS Distributions      -> task_com.apple.driver.AppleHV
53*2c2f96dcSApple OSS Distributions          -> task_com.apple.driver.AppleHV
54*2c2f96dcSApple OSS Distributions      ...
55*2c2f96dcSApple OSS Distributions```
56*2c2f96dcSApple OSS Distributions
57*2c2f96dcSApple OSS DistributionsThe `task` group contains a count of all task references in the system. The
58*2c2f96dcSApple OSS Distributionsfirst-level groups are static and sub-divide task references based on the
59*2c2f96dcSApple OSS Distributionssub-system they come from. `task_external` is used for kext references and each
60*2c2f96dcSApple OSS Distributionskext will be dynamically assigned a reference group as needed (if there's
61*2c2f96dcSApple OSS Distributionsone available). At the bottom level, there's a per-task (local) ref group under
62*2c2f96dcSApple OSS Distributionseach global group.
63*2c2f96dcSApple OSS DistributionsThe exact hierarchy of task references (specifically what per-task reference
64*2c2f96dcSApple OSS Distributionsgroups are created) changes depending on the 'task_refgrp' boot arg.
65*2c2f96dcSApple OSS Distributions
66*2c2f96dcSApple OSS DistributionsTask reference groups can be explored in `lldb` as follows:
67*2c2f96dcSApple OSS Distributions
68*2c2f96dcSApple OSS Distributions```
69*2c2f96dcSApple OSS Distributions(lldb) showglobaltaskrefgrps
70*2c2f96dcSApple OSS Distributionsos_refgrp          name                                           count     retain    release   log
71*2c2f96dcSApple OSS Distributions0xffffff801ace9250 task_kernel                                    68        367663    367595    0x0
72*2c2f96dcSApple OSS Distributions0xffffff801ace9288 task_internal                                  974       4953      3979      0x0
73*2c2f96dcSApple OSS Distributions0xffffff801ace92c0 task_mig                                       0         3670      3670      0x0
74*2c2f96dcSApple OSS Distributions0xffffff801ace9218 task_external                                  35        108       73        0x0
75*2c2f96dcSApple OSS Distributions0xffffff9369dc7b20 task_com.apple.iokit.IOAcceleratorFamily2      29        77        48        0x0
76*2c2f96dcSApple OSS Distributions0xffffff936a3f0a20 task_com.apple.iokit.CoreAnalyticsFamily       1         1         0         0x0
77*2c2f96dcSApple OSS Distributions0xffffff936a22cb20 task_com.apple.iokit.EndpointSecurity          0         1         1         0x0
78*2c2f96dcSApple OSS Distributions0xffffff936a283f60 task_com.apple.iokit.IOSurface                 5         5         0         0x0
79*2c2f96dcSApple OSS Distributions0xffffff936a3f08a0 task_com.apple.security.sandbox                0         24        24        0x0
80*2c2f96dcSApple OSS Distributions
81*2c2f96dcSApple OSS Distributions```
82*2c2f96dcSApple OSS Distributions
83*2c2f96dcSApple OSS DistributionsDisplay a task's reference groups:
84*2c2f96dcSApple OSS Distributions
85*2c2f96dcSApple OSS Distributions```
86*2c2f96dcSApple OSS Distributions(lldb) showtaskrefgrps kernel_task
87*2c2f96dcSApple OSS Distributionsos_refgrp          name                                           count     retain    release   log
88*2c2f96dcSApple OSS Distributions0xffffff936a4b9200 task_local_kernel                              1         6         5         0x0
89*2c2f96dcSApple OSS Distributions0xffffff936a4b9238 task_local_internal                            132       619       487       0x0
90*2c2f96dcSApple OSS Distributions```
91*2c2f96dcSApple OSS Distributions
92*2c2f96dcSApple OSS DistributionsThe reference group hierarchy for a specific group can be displayed as follows:
93*2c2f96dcSApple OSS Distributions
94*2c2f96dcSApple OSS Distributions```
95*2c2f96dcSApple OSS Distributions(lldb) showosrefgrphierarchy 0xffffff936a3f08a0
96*2c2f96dcSApple OSS Distributions0xffffff801ace9988 all                                            1121      377740    376619    0x0
97*2c2f96dcSApple OSS Distributions0xffffff801ace91e0 task                                           1077      376394    375317    0x0
98*2c2f96dcSApple OSS Distributions0xffffff801ace9218 task_external                                  35        108       73        0x0
99*2c2f96dcSApple OSS Distributions0xffffff936a3f08a0 task_com.apple.security.sandbox                0         24        24        0x0
100*2c2f96dcSApple OSS Distributions```
101*2c2f96dcSApple OSS Distributions
102*2c2f96dcSApple OSS DistributionsReference groups are normally disabled, but task reference group statistics
103*2c2f96dcSApple OSS Distributions*are* enabled by default (for `RELEASE` builds, reference groups are not available
104*2c2f96dcSApple OSS Distributionsat all). Backtrace logging for all groups is disabled, including task reference
105*2c2f96dcSApple OSS Distributionsgroups. To enable backtrace logging and reference group statistics, the `rlog`
106*2c2f96dcSApple OSS Distributionsboot-arg must be used. Backtrace logging for task reference groups is only
107*2c2f96dcSApple OSS Distributionsenabled when `rlog` has been set to a suitable value.
108*2c2f96dcSApple OSS Distributions
109*2c2f96dcSApple OSS DistributionsFor example
110*2c2f96dcSApple OSS Distributions
111*2c2f96dcSApple OSS DistributionsTo enable statistics for all reference groups and backtrace logging for the
112*2c2f96dcSApple OSS Distributions*task_external* reference group in particular:
113*2c2f96dcSApple OSS Distributions
114*2c2f96dcSApple OSS Distributions```
115*2c2f96dcSApple OSS Distributionsnvram boot-args="rlog=task_external ..."
116*2c2f96dcSApple OSS Distributions```
117*2c2f96dcSApple OSS Distributions
118*2c2f96dcSApple OSS Distributions```
119*2c2f96dcSApple OSS Distributions(lldb) showglobaltaskrefgrps
120*2c2f96dcSApple OSS Distributionsos_refgrp          name                                           count     retain    release   log
121*2c2f96dcSApple OSS Distributions0xffffff801e0e9250 task_kernel                                    1259      132739    131480    0x0
122*2c2f96dcSApple OSS Distributions0xffffff801e0e9218 task_external                                  35        100       65        0xffffffa05b3fc000
123*2c2f96dcSApple OSS Distributions0xffffff936d117be0 task_com.apple.iokit.IOAcceleratorFamily2      29        77        48        0x0
124*2c2f96dcSApple OSS Distributions0xffffff936db9fa20 task_com.apple.iokit.CoreAnalyticsFamily       1         1         0         0x0
125*2c2f96dcSApple OSS Distributions0xffffff936d9dbb20 task_com.apple.iokit.EndpointSecurity          0         1         1         0x0
126*2c2f96dcSApple OSS Distributions0xffffff936da324e0 task_com.apple.iokit.IOSurface                 5         5         0         0x0
127*2c2f96dcSApple OSS Distributions0xffffff936db9f8a0 task_com.apple.security.sandbox                0         16        16        0x0
128*2c2f96dcSApple OSS Distributions
129*2c2f96dcSApple OSS Distributions
130*2c2f96dcSApple OSS Distributions(lldb) showbtlogrecords 0xffffffa05b3fc000
131*2c2f96dcSApple OSS Distributions-------- OP 1 Stack Index 0 with active refs 1 of 165 --------
132*2c2f96dcSApple OSS Distributions0xffffff801da7c1cb <kernel.development`ref_log_op at refcnt.c:107>
133*2c2f96dcSApple OSS Distributions0xffffff801d27c35d <kernel.development`task_reference_grp at task_ref.c:274>
134*2c2f96dcSApple OSS Distributions0xffffff801ecc014e <EndpointSecurity`VMMap::taskSelf()>
135*2c2f96dcSApple OSS Distributions0xffffff801eccc845 <EndpointSecurity`EndpointSecurityClient::create(ScopedPointer<MachSendWrapper> const&, proc*, ScopedPointer<EndpointSecurityExternalClient> const&, es_client_config_t const&)>
136*2c2f96dcSApple OSS Distributions...
137*2c2f96dcSApple OSS Distributions```
138