1# zx_object_get_info
2
3## NAME
4
5<!-- Updated by update-docs-from-abigen, do not edit. -->
6
7object_get_info - query information about an object
8
9## SYNOPSIS
10
11<!-- Updated by update-docs-from-abigen, do not edit. -->
12
13```
14#include <zircon/syscalls.h>
15
16zx_status_t zx_object_get_info(zx_handle_t handle,
17                               uint32_t topic,
18                               void* buffer,
19                               size_t buffer_size,
20                               size_t* actual,
21                               size_t* avail);
22```
23
24## DESCRIPTION
25
26`zx_object_get_info()` requests information about the provided handle (or the
27object the handle refers to). The *topic* parameter indicates what specific
28information is desired.
29
30*buffer* is a pointer to a buffer of size *buffer_size* to return the
31information.
32
33*actual* is an optional pointer to return the number of records that were
34written to buffer.
35
36*avail* is an optional pointer to return the number of records that are
37available to read.
38
39If the buffer is insufficiently large, *avail* will be larger than *actual*.
40
41[TOC]
42
43## TOPICS
44
45### ZX_INFO_HANDLE_VALID
46
47*handle* type: **Any**
48
49*buffer* type: **n/a**
50
51Returns **ZX_OK** if *handle* is valid, or **ZX_ERR_BAD_HANDLE** otherwise. No
52records are returned and *buffer* may be NULL.
53
54### ZX_INFO_HANDLE_BASIC
55
56*handle* type: **Any**
57
58*buffer* type: `zx_info_handle_basic_t[1]`
59
60```
61typedef struct zx_info_handle_basic {
62    // The unique id assigned by kernel to the object referenced by the
63    // handle.
64    zx_koid_t koid;
65
66    // The immutable rights assigned to the handle. Two handles that
67    // have the same koid and the same rights are equivalent and
68    // interchangeable.
69    zx_rights_t rights;
70
71    // The object type: channel, event, socket, etc.
72    uint32_t type;                // zx_obj_type_t;
73
74    // If the object referenced by the handle is related to another (such
75    // as the other end of a channel, or the parent of a job) then
76    // |related_koid| is the koid of that object, otherwise it is zero.
77    // This relationship is immutable: an object's |related_koid| does
78    // not change even if the related object no longer exists.
79    zx_koid_t related_koid;
80
81    // Set to ZX_OBJ_PROP_WAITABLE if the object referenced by the
82    // handle can be waited on; zero otherwise.
83    uint32_t props;               // zx_obj_props_t;
84} zx_info_handle_basic_t;
85```
86
87### ZX_INFO_HANDLE_COUNT
88
89*handle* type: **Any**
90
91*buffer* type: `zx_info_handle_count_t[1]`
92
93```
94typedef struct zx_info_handle_count {
95    // The number of outstanding handles to a kernel object.
96    uint32_t handle_count;
97} zx_info_handle_count_t;
98```
99The *handle_count* should only be used as a debugging aid. Do not use it
100to check that an untrusted processes cannot modify a kernel object. Due to
101asynchronous nature of the system scheduler, there might be a time window
102during which it is possible for an object to be modified by a previous handle
103owner even as the last handle is transferred from one process to another.
104
105### ZX_INFO_PROCESS_HANDLE_STATS
106
107*handle* type: **Process**
108
109*buffer* type: `zx_info_process_handle_stats_t[1]`
110
111```
112typedef struct zx_info_process_handle_stats {
113    // The number of outstanding handles to kernel objects of each type.
114    uint32_t handle_count[ZX_OBJ_TYPE_LAST];
115} zx_info_process_handle_stats_t;
116```
117
118### ZX_INFO_PROCESS
119
120*handle* type: **Process**
121
122*buffer* type: `zx_info_process_t[1]`
123
124```
125typedef struct zx_info_process {
126    // The process's return code; only valid if |exited| is true.
127    // Guaranteed to be non-zero if the process was killed by |zx_task_kill|.
128    int64_t return_code;
129
130    // True if the process has ever left the initial creation state,
131    // even if it has exited as well.
132    bool started;
133
134    // If true, the process has exited and |return_code| is valid.
135    bool exited;
136
137    // True if a debugger is attached to the process.
138    bool debugger_attached;
139} zx_info_process_t;
140```
141
142### ZX_INFO_PROCESS_THREADS
143
144*handle* type: **Process**
145
146*buffer* type: `zx_koid_t[n]`
147
148Returns an array of `zx_koid_t`, one for each running thread in the Process at
149that moment in time.
150
151N.B. Getting the list of threads is inherently racy.
152This can be somewhat mitigated by first suspending all the threads,
153but note that an external thread can create new threads.
154*actual* will contain the number of threads returned in *buffer*.
155*avail* will contain the total number of threads of the process at
156the time the list of threads was obtained, it could be larger than *actual*.
157
158### ZX_INFO_THREAD
159
160*handle* type: **Thread**
161
162*buffer* type: `zx_info_thread_t[1]`
163
164```
165typedef struct zx_info_thread {
166    // One of ZX_THREAD_STATE_* values.
167    uint32_t state;
168
169    // If |state| is ZX_THREAD_STATE_BLOCKED_EXCEPTION, the thread has gotten
170    // an exception and is waiting for the exception to be handled by the
171    // specified port.
172    // The value is one of ZX_EXCEPTION_PORT_TYPE_*.
173    uint32_t wait_exception_port_type;
174} zx_info_thread_t;
175```
176
177The values in this struct are mainly for informational and debugging
178purposes at the moment.
179
180The various **ZX_THREAD_STATE_** values are defined by
181
182```
183#include <zircon/syscalls/object.h>
184```
185
186*   **ZX_THREAD_STATE_NEW**: The thread has been created but it has not started running yet.
187*   **ZX_THREAD_STATE_RUNNING**: The thread is running user code normally.
188*   **ZX_THREAD_STATE_SUSPENDED**: Stopped due to [`zx_task_suspend()`].
189*   **ZX_THREAD_STATE_BLOCKED**: In a syscall or handling an exception.
190    This value is never returned by itself.
191	See **ZX_THREAD_STATE_BLOCKED_\*** below.
192*   **ZX_THREAD_STATE_DYING**: The thread is in the process of being terminated,
193    but it has not been stopped yet.
194*   **ZX_THREAD_STATE_DEAD**: The thread has stopped running.
195
196When a thread is stopped inside a blocking syscall, or stopped in an
197exception, the value returned in **state** is one of the following:
198
199*   **ZX_THREAD_STATE_BLOCKED_EXCEPTION**: The thread is stopped in an exception.
200*   **ZX_THREAD_STATE_BLOCKED_SLEEPING**: The thread is stopped in [`zx_nanosleep()`].
201*   **ZX_THREAD_STATE_BLOCKED_FUTEX**: The thread is stopped in [`zx_futex_wait()`].
202*   **ZX_THREAD_STATE_BLOCKED_PORT**: The thread is stopped in [`zx_port_wait()`].
203*   **ZX_THREAD_STATE_BLOCKED_CHANNEL**: The thread is stopped in [`zx_channel_call()`].
204*   **ZX_THREAD_STATE_BLOCKED_WAIT_ONE**: The thread is stopped in [`zx_object_wait_one()`].
205*   **ZX_THREAD_STATE_BLOCKED_WAIT_MANY**: The thread is stopped in [`zx_object_wait_many()`].
206*   **ZX_THREAD_STATE_BLOCKED_INTERRUPT**: The thread is stopped in [`zx_interrupt_wait()`].
207
208The various **ZX_EXCEPTION_PORT_TYPE_** values are defined by
209
210```
211#include <zircon/syscalls/exception.h>
212```
213
214*   **ZX_EXCEPTION_PORT_TYPE_NONE**
215*   **ZX_EXCEPTION_PORT_TYPE_DEBUGGER**
216*   **ZX_EXCEPTION_PORT_TYPE_THREAD**
217*   **ZX_EXCEPTION_PORT_TYPE_PROCESS**
218*   **ZX_EXCEPTION_PORT_TYPE_JOB**
219*   **ZX_EXCEPTION_PORT_TYPE_JOB_DEBUGGER**
220
221### ZX_INFO_THREAD_EXCEPTION_REPORT
222
223*handle* type: **Thread**
224
225*buffer* type: `zx_exception_report_t[1]`
226
227```
228#include <zircon/syscalls/exception.h>
229```
230
231If the thread is currently in an exception and is waiting for an exception
232response, then this returns the exception report as a single
233`zx_exception_report_t`, with status **ZX_OK**.
234
235Returns **ZX_ERR_BAD_STATE** if the thread is not in an exception and waiting for
236an exception response.
237
238### ZX_INFO_THREAD_STATS
239
240*handle* type: **Thread**
241
242*buffer* type: `zx_info_thread_stats[1]`
243
244```
245typedef struct zx_info_thread_stats {
246    // Total accumulated running time of the thread.
247    zx_duration_t total_runtime;
248} zx_info_thread_stats_t;
249```
250
251
252### ZX_INFO_CPU_STATS
253
254Note: many values of this topic are being retired in favor of a different mechanism.
255
256*handle* type: **Resource** (Specifically, the root resource)
257
258*buffer* type: `zx_info_cpu_stats_t[1]`
259
260```
261typedef struct zx_info_cpu_stats {
262    uint32_t cpu_number;
263    uint32_t flags;
264
265    zx_duration_t idle_time;
266
267    // kernel scheduler counters
268    uint64_t reschedules;
269    uint64_t context_switches;
270    uint64_t irq_preempts;
271    uint64_t preempts;
272    uint64_t yields;
273
274    // cpu level interrupts and exceptions
275    uint64_t ints;          // hardware interrupts, minus timer interrupts
276                            // inter-processor interrupts
277    uint64_t timer_ints;    // timer interrupts
278    uint64_t timers;        // timer callbacks
279    uint64_t page_faults;   // (deprecated, returns 0)
280    uint64_t exceptions;    // (deprecated, returns 0)
281    uint64_t syscalls;
282
283    // inter-processor interrupts
284    uint64_t reschedule_ipis;
285    uint64_t generic_ipis;
286} zx_info_cpu_stats_t;
287```
288
289### ZX_INFO_VMAR
290
291*handle* type: **VM Address Region**
292
293*buffer* type: `zx_info_vmar_t[1]`
294
295```
296typedef struct zx_info_vmar {
297    // Base address of the region.
298    uintptr_t base;
299
300    // Length of the region, in bytes.
301    size_t len;
302} zx_info_vmar_t;
303```
304
305This returns a single `zx_info_vmar_t` that describes the range of address
306space that the VMAR occupies.
307
308### ZX_INFO_VMO
309
310*handle* type: **VM Object**
311
312*buffer* type: `zx_info_vmo_t[1]`
313
314```
315typedef struct zx_info_vmo {
316    // The koid of this VMO.
317    zx_koid_t koid;
318
319    // The name of this VMO.
320    char name[ZX_MAX_NAME_LEN];
321
322    // The size of this VMO.
323    uint64_t size_bytes;
324
325    // If this VMO is a clone, the koid of its parent. Otherwise, zero.
326    zx_koid_t parent_koid;
327
328    // The number of clones of this VMO, if any.
329    size_t num_children;
330
331    // The number of times this VMO is currently mapped into VMARs.
332    size_t num_mappings;
333
334    // An estimate of the number of unique address spaces that
335    // this VMO is mapped into.
336    size_t share_count;
337
338    // Bitwise OR of ZX_INFO_VMO_* values.
339    uint32_t flags;
340
341    // If |ZX_INFO_VMO_TYPE(flags) == ZX_INFO_VMO_TYPE_PAGED|, the amount of
342    // memory currently allocated to this VMO.
343    uint64_t committed_bytes;
344
345    // If |flags & ZX_INFO_VMO_VIA_HANDLE|, the handle rights.
346    // Undefined otherwise.
347    zx_rights_t handle_rights;
348
349    // VMO creation options. This is a bitmask of
350    // kResizable    = (1u << 0);
351    // kContiguous   = (1u << 1);
352    uint32_t create_options;
353
354    // VMO mapping cache policy. One of ZX_CACHE_POLICY_*
355    uint32_t cache_policy;
356} zx_info_vmo_t;
357```
358
359This returns a single `zx_info_vmo_t` that describes various attributes of
360the VMO.
361
362### ZX_INFO_SOCKET
363
364*handle* type: **Socket**
365
366*buffer* type: `zx_info_socket_t[1]`
367
368```
369typedef struct zx_info_socket {
370    // The options passed to zx_socket_create().
371    uint32_t options;
372
373    // The maximum size of the receive buffer of a socket, in bytes.
374    //
375    // The receive buffer may become full at a capacity less than the maximum
376    // due to overhead.
377    size_t rx_buf_max;
378
379    // The size of the receive buffer of a socket, in bytes.
380    size_t rx_buf_size;
381
382    // The amount of data, in bytes, that is available for reading in a single
383    // zx_socket_read call.
384    //
385    // For stream sockets, this value will match |rx_buf_size|. For datagram
386    // sockets, this value will be the size of the next datagram in the receive
387    // buffer.
388    size_t rx_buf_available;
389
390    // The maximum size of the transmit buffer of a socket, in bytes.
391    //
392    // The transmit buffer may become full at a capacity less than the maximum
393    // due to overhead.
394    //
395    // Will be zero if the peer endpoint is closed.
396    size_t tx_buf_max;
397
398    // The size of the transmit buffer of a socket, in bytes.
399    //
400    // Will be zero if the peer endpoint is closed.
401    size_t tx_buf_size;
402} zx_info_socket_t;
403```
404
405### ZX_INFO_JOB_CHILDREN
406
407*handle* type: **Job**
408
409*buffer* type: `zx_koid_t[n]`
410
411Returns an array of `zx_koid_t`, one for each direct child Job of the provided
412Job handle.
413
414### ZX_INFO_JOB_PROCESSES
415
416*handle* type: **Job**
417
418*buffer* type: `zx_koid_t[n]`
419
420Returns an array of `zx_koid_t`, one for each direct child Process of the
421provided Job handle.
422
423### ZX_INFO_TASK_STATS
424
425*handle* type: **Process**
426
427*buffer* type: `zx_info_task_stats_t[1]`
428
429Returns statistics about resources (e.g., memory) used by a task.
430
431```
432typedef struct zx_info_task_stats {
433    // The total size of mapped memory ranges in the task.
434    // Not all will be backed by physical memory.
435    size_t mem_mapped_bytes;
436
437    // For the fields below, a byte is considered committed if it's backed by
438    // physical memory. Some of the memory may be double-mapped, and thus
439    // double-counted.
440
441    // Committed memory that is only mapped into this task.
442    size_t mem_private_bytes;
443
444    // Committed memory that is mapped into this and at least one other task.
445    size_t mem_shared_bytes;
446
447    // A number that estimates the fraction of mem_shared_bytes that this
448    // task is responsible for keeping alive.
449    //
450    // An estimate of:
451    //   For each shared, committed byte:
452    //   mem_scaled_shared_bytes += 1 / (number of tasks mapping this byte)
453    //
454    // This number is strictly smaller than mem_shared_bytes.
455    size_t mem_scaled_shared_bytes;
456} zx_info_task_stats_t;
457```
458
459Additional errors:
460
461*   **ZX_ERR_BAD_STATE**: If the target process has terminated
462
463### ZX_INFO_PROCESS_MAPS
464
465*handle* type: **Process** other than your own, with **ZX_RIGHT_READ**
466
467*buffer* type: `zx_info_maps_t[n]`
468
469The `zx_info_maps_t` array is a depth-first pre-order walk of the target
470process's Aspace/VMAR/Mapping tree. As per the pre-order traversal base
471addresses will be in ascending order.
472
473```
474typedef struct zx_info_maps {
475    // Name if available; empty string otherwise.
476    char name[ZX_MAX_NAME_LEN];
477    // Base address.
478    zx_vaddr_t base;
479    // Size in bytes.
480    size_t size;
481
482    // The depth of this node in the tree.
483    // Can be used for indentation, or to rebuild the tree from an array
484    // of zx_info_maps_t entries, which will be in depth-first pre-order.
485    size_t depth;
486    // The type of this entry; indicates which union entry is valid.
487    uint32_t type; // zx_info_maps_type_t
488    union {
489        zx_info_maps_mapping_t mapping;
490        // No additional fields for other types.
491    } u;
492} zx_info_maps_t;
493```
494
495The *depth* field of each entry describes its relationship to the nodes that
496come before it. Depth 0 is the root Aspace, depth 1 is the root VMAR, and all
497other entries have depth 2 or greater.
498
499To get a full picture of how a process uses its VMOs and how a VMO is used
500by various processes, you may need to combine this information with
501ZX_INFO_PROCESS_VMOS.
502
503See the `vmaps` command-line tool for an example user of this topic, and to dump
504the maps of arbitrary processes by koid.
505
506Additional errors:
507
508*   **ZX_ERR_ACCESS_DENIED**: If the appropriate rights are missing, or if a
509    process attempts to call this on a handle to itself. It's not safe to
510    examine yourself: *buffer* will live inside the Aspace being examined, and
511    the kernel can't safely fault in pages of the buffer while walking the
512    Aspace.
513*   **ZX_ERR_BAD_STATE**: If the target process has terminated, or if its
514    address space has been destroyed
515
516### ZX_INFO_PROCESS_VMOS
517
518*handle* type: **Process** other than your own, with **ZX_RIGHT_READ**
519
520*buffer* type: `zx_info_vmos_t[n]`
521
522The `zx_info_vmos_t` array is list of all VMOs pointed to by the target process.
523Some VMOs are mapped, some are pointed to by handles, and some are both.
524
525**Note**: The same VMO may appear multiple times due to multiple
526mappings/handles. Also, because VMOs can change as the target process runs,
527the same VMO may have different values each time it appears. It is the
528caller's job to resolve any duplicates.
529
530To get a full picture of how a process uses its VMOs and how a VMO is used
531by various processes, you may need to combine this information with
532ZX_INFO_PROCESS_MAPS.
533
534```
535// Describes a VMO.
536typedef struct zx_info_vmo {
537    // The koid of this VMO.
538    zx_koid_t koid;
539
540    // The name of this VMO.
541    char name[ZX_MAX_NAME_LEN];
542
543    // The size of this VMO; i.e., the amount of virtual address space it
544    // would consume if mapped.
545    uint64_t size_bytes;
546
547    // If this VMO is a clone, the koid of its parent. Otherwise, zero.
548    // See |flags| for the type of clone.
549    zx_koid_t parent_koid;
550
551    // The number of clones of this VMO, if any.
552    size_t num_children;
553
554    // The number of times this VMO is currently mapped into VMARs.
555    // Note that the same process will often map the same VMO twice,
556    // and both mappings will be counted here. (I.e., this is not a count
557    // of the number of processes that map this VMO; see share_count.)
558    size_t num_mappings;
559
560    // An estimate of the number of unique address spaces that
561    // this VMO is mapped into. Every process has its own address space,
562    // and so does the kernel.
563    size_t share_count;
564
565    // Bitwise OR of ZX_INFO_VMO_* values.
566    uint32_t flags;
567
568    // If |ZX_INFO_VMO_TYPE(flags) == ZX_INFO_VMO_TYPE_PAGED|, the amount of
569    // memory currently allocated to this VMO; i.e., the amount of physical
570    // memory it consumes. Undefined otherwise.
571    uint64_t committed_bytes;
572
573    // If |flags & ZX_INFO_VMO_VIA_HANDLE|, the handle rights.
574    // Undefined otherwise.
575    zx_rights_t handle_rights;
576} zx_info_vmo_t;
577```
578
579See the `vmos` command-line tool for an example user of this topic, and to dump
580the VMOs of arbitrary processes by koid.
581
582### ZX_INFO_KMEM_STATS
583
584*handle* type: **Resource** (Specifically, the root resource)
585
586*buffer* type: `zx_info_kmem_stats_t[1]`
587
588Returns information about kernel memory usage. It can be expensive to gather.
589
590```
591typedef struct zx_info_kmem_stats {
592    // The total amount of physical memory available to the system.
593    size_t total_bytes;
594
595    // The amount of unallocated memory.
596    size_t free_bytes;
597
598    // The amount of memory reserved by and mapped into the kernel for reasons
599    // not covered by other fields in this struct. Typically for readonly data
600    // like the ram disk and kernel image, and for early-boot dynamic memory.
601    size_t wired_bytes;
602
603    // The amount of memory allocated to the kernel heap.
604    size_t total_heap_bytes;
605
606    // The portion of |total_heap_bytes| that is not in use.
607    size_t free_heap_bytes;
608
609    // The amount of memory committed to VMOs, both kernel and user.
610    // A superset of all userspace memory.
611    // Does not include certain VMOs that fall under |wired_bytes|.
612    //
613    // TODO(dbort): Break this into at least two pieces: userspace VMOs that
614    // have koids, and kernel VMOs that don't. Or maybe look at VMOs
615    // mapped into the kernel aspace vs. everything else.
616    size_t vmo_bytes;
617
618    // The amount of memory used for architecture-specific MMU metadata
619    // like page tables.
620    size_t mmu_overhead_bytes;
621
622    // Non-free memory that isn't accounted for in any other field.
623    size_t other_bytes;
624} zx_info_kmem_stats_t;
625```
626
627### ZX_INFO_RESOURCE
628
629*handle* type: **Resource**
630
631*buffer* type: `zx_info_resource_t[1]`
632
633Returns information about a resource object via its handle.
634
635```
636typedef struct zx_info_resource {
637    // The resource kind
638    uint32_t kind;
639    // Resource's low value (inclusive)
640    uint64_t low;
641    // Resource's high value (inclusive)
642    uint64_t high;
643} zx_info_resource_t;
644```
645
646The resource kind is one of
647
648*   **ZX_RSRC_KIND_ROOT**
649*   **ZX_RSRC_KIND_MMIO**
650*   **ZX_RSRC_KIND_IOPORT**
651*   **ZX_RSRC_KIND_IRQ**
652*   **ZX_RSRC_KIND_HYPERVISOR**
653*   **ZX_RSRC_KIND_VMEX**
654*   **ZX_RSRC_KIND_SMC**
655
656### ZX_INFO_BTI
657
658*handle* type: **Bus Transaction Initiator**
659
660*buffer* type: `zx_info_bti_t[1]`
661
662```
663typedef struct zx_info_bti {
664    // zx_bti_pin will always be able to return addresses that are contiguous for at
665    // least this many bytes.  E.g. if this returns 1MB, then a call to
666    // zx_bti_pin() with a size of 2MB will return at most two physically-contiguous runs.
667    // If the size were 2.5MB, it will return at most three physically-contiguous runs.
668    uint64_t minimum_contiguity;
669
670    // The number of bytes in the device's address space (UINT64_MAX if 2^64).
671    uint64_t aspace_size;
672} zx_info_bti_t;
673```
674
675## RIGHTS
676
677<!-- Updated by update-docs-from-abigen, do not edit. -->
678
679If *topic* is **ZX_INFO_PROCESS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
680
681If *topic* is **ZX_INFO_PROCESS_THREADS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_ENUMERATE**.
682
683If *topic* is **ZX_INFO_JOB_CHILDREN**, *handle* must be of type **ZX_OBJ_TYPE_JOB** and have **ZX_RIGHT_ENUMERATE**.
684
685If *topic* is **ZX_INFO_JOB_PROCESSES**, *handle* must be of type **ZX_OBJ_TYPE_JOB** and have **ZX_RIGHT_ENUMERATE**.
686
687If *topic* is **ZX_INFO_THREAD**, *handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_INSPECT**.
688
689If *topic* is **ZX_INFO_THREAD_EXCEPTION_REPORT**, *handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_INSPECT**.
690
691If *topic* is **ZX_INFO_THREAD_STATS**, *handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_INSPECT**.
692
693If *topic* is **ZX_INFO_TASK_STATS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
694
695If *topic* is **ZX_INFO_PROCESS_MAPS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
696
697If *topic* is **ZX_INFO_PROCESS_VMOS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
698
699If *topic* is **ZX_INFO_VMO**, *handle* must be of type **ZX_OBJ_TYPE_VMO**.
700
701If *topic* is **ZX_INFO_VMAR**, *handle* must be of type **ZX_OBJ_TYPE_VMAR** and have **ZX_RIGHT_INSPECT**.
702
703If *topic* is **ZX_INFO_CPU_STATS**, *handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
704
705If *topic* is **ZX_INFO_KMEM_STATS**, *handle* must have resource kind **ZX_RSRC_KIND_ROOT**.
706
707If *topic* is **ZX_INFO_RESOURCE**, *handle* must be of type **ZX_OBJ_TYPE_RESOURCE** and have **ZX_RIGHT_INSPECT**.
708
709If *topic* is **ZX_INFO_HANDLE_COUNT**, *handle* must have **ZX_RIGHT_INSPECT**.
710
711If *topic* is **ZX_INFO_BTI**, *handle* must be of type **ZX_OBJ_TYPE_BTI** and have **ZX_RIGHT_INSPECT**.
712
713If *topic* is **ZX_INFO_PROCESS_HANDLE_STATS**, *handle* must be of type **ZX_OBJ_TYPE_PROCESS** and have **ZX_RIGHT_INSPECT**.
714
715If *topic* is **ZX_INFO_SOCKET**, *handle* must be of type **ZX_OBJ_TYPE_SOCKET** and have **ZX_RIGHT_INSPECT**.
716
717## RETURN VALUE
718
719`zx_object_get_info()` returns **ZX_OK** on success. In the event of
720failure, a negative error value is returned.
721
722## ERRORS
723
724**ZX_ERR_BAD_HANDLE** *handle* is not a valid handle.
725
726**ZX_ERR_WRONG_TYPE** *handle* is not an appropriate type for *topic*
727
728**ZX_ERR_ACCESS_DENIED**: If *handle* does not have the necessary rights for the
729operation.
730
731**ZX_ERR_INVALID_ARGS** *buffer*, *actual*, or *avail* are invalid pointers.
732
733**ZX_ERR_NO_MEMORY**  Failure due to lack of memory.
734There is no good way for userspace to handle this (unlikely) error.
735In a future build this error will no longer occur.
736
737**ZX_ERR_BUFFER_TOO_SMALL** The *topic* returns a fixed number of records, but the
738provided buffer is not large enough for these records.
739
740**ZX_ERR_NOT_SUPPORTED** *topic* does not exist.
741
742## EXAMPLES
743
744```
745bool is_handle_valid(zx_handle_t handle) {
746    return zx_object_get_info(
747        handle, ZX_INFO_HANDLE_VALID, NULL, 0, NULL, NULL) == ZX_OK;
748}
749
750zx_koid_t get_object_koid(zx_handle_t handle) {
751    zx_info_handle_basic_t info;
752    if (zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC,
753                           &info, sizeof(info), NULL, NULL) != ZX_OK) {
754        return 0;
755    }
756    return info.koid;
757}
758
759void examine_threads(zx_handle_t proc) {
760    zx_koid_t threads[128];
761    size_t count, avail;
762
763    if (zx_object_get_info(proc, ZX_INFO_PROCESS_THREADS, threads,
764                           sizeof(threads), &count, &avail) != ZX_OK) {
765        // Error!
766    } else {
767        if (avail > count) {
768            // More threads than space in array;
769            // could call again with larger array.
770        }
771        for (size_t n = 0; n < count; n++) {
772            do_something(thread[n]);
773        }
774    }
775}
776```
777
778## SEE ALSO
779
780 - [`zx_handle_close()`]
781 - [`zx_handle_duplicate()`]
782 - [`zx_handle_replace()`]
783 - [`zx_object_get_child()`]
784
785<!-- References updated by update-docs-from-abigen, do not edit. -->
786
787[`zx_channel_call()`]: channel_call.md
788[`zx_futex_wait()`]: futex_wait.md
789[`zx_handle_close()`]: handle_close.md
790[`zx_handle_duplicate()`]: handle_duplicate.md
791[`zx_handle_replace()`]: handle_replace.md
792[`zx_interrupt_wait()`]: interrupt_wait.md
793[`zx_nanosleep()`]: nanosleep.md
794[`zx_object_get_child()`]: object_get_child.md
795[`zx_object_wait_many()`]: object_wait_many.md
796[`zx_object_wait_one()`]: object_wait_one.md
797[`zx_port_wait()`]: port_wait.md
798[`zx_task_suspend()`]: task_suspend.md
799