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