2 #include <System/sys/kdebug.h>
3 #include <darwintest.h>
4 #include <darwintest_utils.h>
5 #include <dispatch/dispatch.h>
10 #include <mach/mach.h>
11 #include <mach/policy.h>
12 #include <os/assumes.h>
13 #include <os/overflow.h>
20 #include <sys/event.h>
22 #include <sys/proc_info.h>
24 #include <sys/sysctl.h>
25 #include <sys/vnode.h>
29 #define ACT_CHANGE_UID 1
30 #define ACT_CHANGE_RUID 2
41 #define CONF_THREAD_NAME "test_child_thread"
42 #define CONF_CMD_NAME getprogname()
43 #define CONF_PROC_COUNT 20
44 #define CONF_BLK_SIZE 4096
45 #define CONF_UID_VAL 999U
46 #define CONF_RUID_VAL 998U
47 #define CONF_GID_VAL 997U
48 #define CONF_NICE_VAL 5
49 #define CONF_NUM_THREADS 2
51 #define BASEPRI_DEFAULT 31
52 #define MAXPRI_USER 63
54 #define CONF_OPN_FILE_COUNT 3
55 #define CONF_TMP_FILE_PATH "/tmp/testfile"
57 uint32_t get_tty_dev(void);
59 #define WAIT_FOR_CHILDREN(pipefd, action, child_count) \
62 if (child_count == 1) { \
63 int child_ret_action = 999; \
64 while (child_ret_action != action) { \
65 ret = read(pipefd, &child_ret_action, sizeof(child_ret_action)); \
68 int child_ready_count = child_count * (int)sizeof(action); \
71 while (child_ready_count) { \
72 ret = read(pipefd, &action, (int)sizeof(action)); \
74 child_ready_count -= ret; \
76 T_FAIL("ERROR: Could not read from pipe() : %d", errno); \
79 T_FAIL("ERROR: Child action failed with error %d", action); \
85 #define PROC_INFO_CALL(struct_name, pid, flavor, proc_arg) \
87 struct struct_name * struct_var = malloc(sizeof(struct struct_name)); \
89 T_ASSERT_NOTNULL(struct_var, "malloc() for " #flavor); \
90 retval = __proc_info(PROC_INFO_CALL_PIDINFO, pid, flavor, (uint64_t)proc_arg, (user_addr_t)struct_var, \
91 (uint32_t)sizeof(struct struct_name)); \
94 T_EXPECT_POSIX_SUCCESS(retval, "__proc_info call for " #flavor); \
95 T_ASSERT_EQ_INT(retval, (int)sizeof(struct struct_name), "__proc_info call for " #flavor); \
96 ret_structs[i] = (void *)struct_var; \
104 stat(ttyname(1), &buf
);
105 return ((uint32_t)buf
.st_rdev
);
109 * Defined in libsyscall/wrappers/libproc/libproc.c
110 * For API test only. For normal use, please use the libproc API instead.
113 extern int __proc_info(int32_t callnum
, int32_t pid
, uint32_t flavor
, uint64_t arg
, user_addr_t buffer
, int32_t buffersize
);
114 struct proc_config_s
{
118 int child_pipe
[CONF_PROC_COUNT
][2];
119 int child_pids
[CONF_PROC_COUNT
];
120 void * cow_map
; /* memory for cow test */
122 typedef struct proc_config_s
* proc_config_t
;
124 typedef void (^child_action_handler_t
)(proc_config_t proc_config
, int child_id
);
134 P_TASK_INFO_NEW
= 0x80,
143 PREGINFO_PATH
= 0x10000,
144 PREGINFO_PATH_2
= 0x20000,
145 PREGINFO_PATH_3
= 0x40000,
149 static int tmp_fd
= -1;
151 static child_action_handler_t proc_info_listpids_handler
= ^void(proc_config_t proc_config
, int child_id
) {
152 close(proc_config
->parent_pipe
[PIPE_IN
]);
153 close(proc_config
->child_pipe
[child_id
][PIPE_OUT
]);
155 int child_action
= 0;
156 retval
= write(proc_config
->parent_pipe
[PIPE_OUT
], &child_action
, sizeof(child_action
));
158 while (child_action
!= ACT_EXIT
) {
159 retval
= read(proc_config
->child_pipe
[child_id
][PIPE_IN
], &child_action
, sizeof(child_action
));
160 if (retval
== 0 || (retval
== -1 && errno
== EAGAIN
)) {
164 switch (child_action
) {
169 retval
= setuid(CONF_UID_VAL
);
171 case ACT_CHANGE_RUID
:
175 retval
= setreuid(CONF_RUID_VAL
, (uid_t
)-1);
184 if (child_action
!= ACT_EXIT
) {
185 retval
= write(proc_config
->parent_pipe
[PIPE_OUT
], &retval
, sizeof(retval
));
191 close(proc_config
->parent_pipe
[PIPE_OUT
]);
192 close(proc_config
->child_pipe
[child_id
][PIPE_IN
]);
196 static child_action_handler_t proc_info_call_pidinfo_handler
= ^void(proc_config_t proc_config
, int child_id
) {
197 close(proc_config
->parent_pipe
[PIPE_IN
]);
198 close(proc_config
->child_pipe
[child_id
][PIPE_OUT
]);
202 void * tmp_map
= NULL
;
203 dispatch_queue_t q
= NULL
;
204 dispatch_semaphore_t sem
= NULL
;
206 * PHASE 1: Child ready and waits for parent to send next action
208 T_LOG("Child ready to accept action from parent");
209 retval
= write(proc_config
->parent_pipe
[PIPE_OUT
], &action
, sizeof(action
));
211 while (action
!= ACT_EXIT
) {
212 retval
= read(proc_config
->child_pipe
[child_id
][PIPE_IN
], &action
, sizeof(action
));
219 * Change uid, euid, guid, rgid, nice value
220 * Also change the svuid and svgid
222 T_LOG("Child changing uid, euid, rguid, svuid, svgid and nice value");
223 retval
= nice(CONF_NICE_VAL
);
225 T_LOG("(child) ERROR: nice() failed");
228 retval
= setgid(CONF_GID_VAL
);
230 T_LOG("(child) ERROR: setgid() failed");
233 retval
= setreuid((uid_t
)-1, CONF_RUID_VAL
);
235 T_LOG("(child) ERROR: setreuid() failed");
242 * Allocate a page of memory
243 * Copy on write shared memory
245 T_LOG("Child allocating a page of memory, and causing a copy-on-write");
247 tmp_map
= mmap(0, PAGE_SIZE
, PROT_WRITE
, MAP_ANON
| MAP_PRIVATE
, -1, 0);
248 if (tmp_map
== MAP_FAILED
) {
249 T_LOG("(child) ERROR: mmap() failed");
254 * Get the page allocated
256 int * map_ptr
= (int *)tmp_map
;
257 for (i
= 0; i
< (int)(PAGE_SIZE
/ sizeof(int)); i
++) {
261 * Cause copy on write to the page
263 *((int *)(proc_config
->cow_map
)) = 20;
268 T_LOG("Child spending CPU cycles and changing thread name");
271 unsigned long long factorial
= 1;
273 for (j
= 1; j
<= number
; j
++) {
274 factorial
*= (unsigned long long)j
;
276 sysctlbyname("kern.threadname", NULL
, 0, CONF_THREAD_NAME
, strlen(CONF_THREAD_NAME
));
281 * Dispatch for Workq test
283 T_LOG("Child creating a dispatch queue, and dispatching blocks on it");
284 q
= dispatch_queue_create("com.apple.test_proc_info.workqtest",
285 DISPATCH_QUEUE_CONCURRENT
); // dispatch_get_global_queue(0, 0);
286 sem
= dispatch_semaphore_create(0);
288 for (i
= 0; i
< CONF_NUM_THREADS
; i
++) {
291 * Block the thread, do nothing
293 dispatch_semaphore_wait(sem
, DISPATCH_TIME_FOREVER
);
303 for (i
= 0; i
< CONF_NUM_THREADS
; i
++) {
304 dispatch_semaphore_signal(sem
);
309 munmap(tmp_map
, PAGE_SIZE
);
311 if (proc_config
->cow_map
)
312 munmap(proc_config
->cow_map
, PAGE_SIZE
);
318 if (action
!= ACT_EXIT
) {
319 retval
= write(proc_config
->parent_pipe
[PIPE_OUT
], &action
, sizeof(action
));
324 close(proc_config
->parent_pipe
[PIPE_OUT
]);
325 close(proc_config
->child_pipe
[child_id
][PIPE_IN
]);
331 free_proc_config(proc_config_t proc_config
)
337 send_action_to_child_processes(proc_config_t proc_config
, int action
)
340 for (int i
= 0; i
< proc_config
->child_count
; i
++) {
341 err
= write(proc_config
->child_pipe
[i
][PIPE_OUT
], &action
, sizeof(action
));
343 T_ASSERT_POSIX_SUCCESS(err
, "write() to child in send_action");
345 if (action
!= ACT_EXIT
) {
346 WAIT_FOR_CHILDREN(proc_config
->parent_pipe
[PIPE_IN
], action
, proc_config
->child_count
);
351 kill_child_processes(proc_config_t proc_config
)
354 T_LOG("Killing child processes");
355 send_action_to_child_processes(proc_config
, ACT_EXIT
);
356 for (int child_id
= 0; child_id
< proc_config
->child_count
; child_id
++) {
357 close(proc_config
->child_pipe
[child_id
][PIPE_OUT
]);
358 dt_waitpid(proc_config
->child_pids
[child_id
], NULL
, NULL
, 5);
360 T_ASSERT_POSIX_SUCCESS(ret
, "killed child %d", child_id
);
362 close(proc_config
->parent_pipe
[PIPE_IN
]);
363 munmap(proc_config
->cow_map
, PAGE_SIZE
);
364 T_LOG("Killed child processes");
368 spawn_child_processes(int child_count
, child_action_handler_t child_handler
)
371 * Spawn procs for Tests 1.2 and 1.3
373 T_LOG("Spawning child processes...");
374 proc_config_t proc_config
= malloc(sizeof(*proc_config
));
379 proc_config
->proc_grp_id
= getpgid(0);
381 proc_config
->child_count
= child_count
;
383 err
= pipe(proc_config
->parent_pipe
);
385 T_ASSERT_POSIX_SUCCESS(err
, "pipe() call");
388 * Needed for ACT_PHASE3 tests
390 proc_config
->cow_map
= mmap(0, PAGE_SIZE
, PROT_WRITE
, MAP_ANON
| MAP_PRIVATE
, -1, 0);
392 T_ASSERT_NE_PTR(proc_config
->cow_map
, MAP_FAILED
, "cow_map mmap()");
393 *((int *)(proc_config
->cow_map
)) = 10;
398 for (i
= 0; i
< child_count
; i
++) {
399 err
= pipe(proc_config
->child_pipe
[i
]);
401 T_ASSERT_POSIX_SUCCESS(err
, "pipe() call");
406 T_ASSERT_POSIX_SUCCESS(child_pid
, "fork() in parent process for child %d", child_id
);
408 if (child_pid
== 0) {
409 child_handler(proc_config
, child_id
);
411 proc_config
->child_pids
[child_id
] = child_pid
;
413 close(proc_config
->child_pipe
[child_id
][PIPE_IN
]);
416 * Wait for the children processes to spawn
418 close(proc_config
->parent_pipe
[PIPE_OUT
]);
419 WAIT_FOR_CHILDREN(proc_config
->parent_pipe
[PIPE_IN
], action
, child_count
);
425 * All PROC_INFO_CALL_PIDINFO __proc_info calls fire from this function.
426 * T_DECLs require different combinations of structs and different actions
427 * must occur in the child to get the data. Instead of performing the setup
428 * in each T_DECL, this function accepts a bitmap and performs the necessary setup
433 proc_info_caller(int proc_info_opts
, void ** ret_structs
, int * ret_child_pid
)
436 uint64_t * thread_addr
= NULL
;
437 void * map_tmp
= NULL
;
439 proc_config_t proc_config
= spawn_child_processes(1, proc_info_call_pidinfo_handler
);
440 int child_pid
= proc_config
->child_pids
[0];
442 * These tests only require one child.
443 * Some DECLs need to know the child pid, so we pass that back if applicable
445 if (ret_child_pid
!= NULL
) {
446 *ret_child_pid
= child_pid
;
449 if (proc_info_opts
& P_UNIQIDINFO
) {
450 PROC_INFO_CALL(proc_uniqidentifierinfo
, getpid(), PROC_PIDUNIQIDENTIFIERINFO
, 0);
452 if (proc_info_opts
& C_UNIQIDINFO
) {
453 PROC_INFO_CALL(proc_uniqidentifierinfo
, child_pid
, PROC_PIDUNIQIDENTIFIERINFO
, 0);
455 if (proc_info_opts
& PBSD_OLD
) {
456 PROC_INFO_CALL(proc_bsdinfo
, child_pid
, PROC_PIDTBSDINFO
, 0);
460 * Child Phase 2 Fires if opts require it
461 * Small nap after call to give child time to receive and execute the action
464 if (proc_info_opts
>= PBSD
) {
465 send_action_to_child_processes(proc_config
, ACT_PHASE2
);
468 if (proc_info_opts
& PBSD
) {
469 PROC_INFO_CALL(proc_bsdinfo
, child_pid
, PROC_PIDTBSDINFO
, 0);
472 if (proc_info_opts
& PBSD_SHORT
) {
473 PROC_INFO_CALL(proc_bsdshortinfo
, child_pid
, PROC_PIDT_SHORTBSDINFO
, 0);
476 if (proc_info_opts
& PBSD_UNIQID
) {
477 PROC_INFO_CALL(proc_bsdinfowithuniqid
, child_pid
, PROC_PIDT_BSDINFOWITHUNIQID
, 0);
479 if (proc_info_opts
& P_TASK_INFO
) {
480 PROC_INFO_CALL(proc_taskinfo
, child_pid
, PROC_PIDTASKINFO
, 0);
484 * Child Phase 3 Fires
486 if (proc_info_opts
>= P_TASK_INFO_NEW
) {
487 send_action_to_child_processes(proc_config
, ACT_PHASE3
);
490 if (proc_info_opts
& P_TASK_INFO_NEW
) {
491 PROC_INFO_CALL(proc_taskinfo
, child_pid
, PROC_PIDTASKINFO
, 0);
494 if (proc_info_opts
& PALL
) {
495 PROC_INFO_CALL(proc_taskallinfo
, child_pid
, PROC_PIDTASKALLINFO
, 0);
498 * This case breaks the pattern in that its proc_info call requires PALL,
499 * its value is required in some other proc_info calls
500 * and we never put the retval into our ret_structs
502 if (proc_info_opts
& THREAD_ADDR
|| proc_info_opts
& PTHINFO_OLD
|| proc_info_opts
& PTHINFO
|| proc_info_opts
& PINFO_PATH
) {
503 struct proc_taskallinfo
* pall
= malloc(sizeof(struct proc_taskallinfo
));
505 T_ASSERT_NOTNULL(pall
, "malloc() for PROC_TASKALLINFO");
507 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDTASKALLINFO
, (uint32_t)0, (user_addr_t
)pall
,
508 (uint32_t)sizeof(struct proc_taskallinfo
));
510 T_ASSERT_EQ_INT(retval
, (int)sizeof(struct proc_taskallinfo
), "__proc_info call for PROC_PIDTASKALLINFO in THREAD_ADDR");
512 thread_addr
= malloc(sizeof(uint64_t) * (unsigned long)(pall
->ptinfo
.pti_threadnum
+ 1));
513 memset(thread_addr
, 0, sizeof(uint64_t) * (unsigned long)(pall
->ptinfo
.pti_threadnum
+ 1));
515 T_ASSERT_NOTNULL(thread_addr
, "malloc() for PROC_PIDLISTTHREADS");
517 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDLISTTHREADS
, (uint32_t)0, (user_addr_t
)thread_addr
,
518 (int32_t)(sizeof(uint64_t) * (unsigned long)(pall
->ptinfo
.pti_threadnum
+ 1)));
519 T_LOG("(int)((unsigned long)retval / PROC_PIDLISTTHREADS_SIZE: %d",
520 (int)((unsigned long)retval
/ PROC_PIDLISTTHREADS_SIZE
));
521 T_ASSERT_GE_INT((int)((unsigned long)retval
/ PROC_PIDLISTTHREADS_SIZE
), pall
->ptinfo
.pti_threadnum
,
522 "__proc_info call for PROC_PIDLISTTHREADS");
526 if (proc_info_opts
& PTHINFO_OLD
) {
527 PROC_INFO_CALL(proc_threadinfo
, child_pid
, PROC_PIDTHREADINFO
, thread_addr
[0]);
531 * Child Phase 4 Fires
533 if (proc_info_opts
>= PTHINFO
) {
534 send_action_to_child_processes(proc_config
, ACT_PHASE4
);
537 if (proc_info_opts
& PTHINFO
) {
538 PROC_INFO_CALL(proc_threadinfo
, child_pid
, PROC_PIDTHREADINFO
, thread_addr
[0]);
540 if (proc_info_opts
& PTHINFO_64
) {
541 mach_port_name_t child_task
= MACH_PORT_NULL
;
542 thread_array_t child_threads
= NULL
;
543 mach_msg_type_number_t child_thread_count
;
544 thread_identifier_info_data_t child_thread_threadinfo
;
545 mach_msg_type_number_t thread_info_count
= THREAD_IDENTIFIER_INFO_COUNT
;
546 struct proc_threadinfo
* pthinfo_64
= malloc(sizeof(struct proc_threadinfo
));
548 T_ASSERT_NOTNULL(pthinfo_64
, "malloc() for PROC_THREADINFO");
550 retval
= task_for_pid(mach_task_self(), child_pid
, &child_task
);
551 T_ASSERT_EQ_INT(retval
, 0, "task_for_pid for PROC_PIDTHREADID64INFO");
553 retval
= task_threads(child_task
, &child_threads
, &child_thread_count
);
554 T_ASSERT_MACH_SUCCESS(retval
, "task_threads() call for PROC_PIDTHREADID64INFO");
556 retval
= thread_info(child_threads
[0], THREAD_IDENTIFIER_INFO
, (thread_info_t
)&child_thread_threadinfo
, &thread_info_count
);
557 T_ASSERT_MACH_SUCCESS(retval
, "thread_info call for PROC_PIDTHREADID64INFO");
559 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDTHREADID64INFO
, (uint64_t)child_thread_threadinfo
.thread_id
,
560 (user_addr_t
)pthinfo_64
, (uint32_t)sizeof(struct proc_threadinfo
));
561 T_ASSERT_EQ_INT(retval
, (int)sizeof(struct proc_threadinfo
), "__proc_info call for PROC_PIDTHREADID64INFO");
563 ret_structs
[i
] = (void *)pthinfo_64
;
566 mach_port_deallocate(mach_task_self(), child_task
);
567 mach_port_deallocate(mach_task_self(), child_threads
[0]);
568 child_threads
[0] = MACH_PORT_NULL
;
569 child_task
= MACH_PORT_NULL
;
571 if (proc_info_opts
& PINFO_PATH
) {
572 PROC_INFO_CALL(proc_threadwithpathinfo
, child_pid
, PROC_PIDTHREADPATHINFO
, thread_addr
[0]);
575 if (proc_info_opts
& PAI
) {
576 PROC_INFO_CALL(proc_archinfo
, getpid(), PROC_PIDARCHINFO
, 0);
579 if ((proc_info_opts
& PREGINFO
) | (proc_info_opts
& PREGINFO_PATH
) | (proc_info_opts
& PREGINFO_PATH_2
) |
580 (proc_info_opts
& PREGINFO_PATH_3
)) {
581 tmp_fd
= open(CONF_TMP_FILE_PATH
, O_RDWR
| O_CREAT
);
583 for (int j
= 0; j
< 100; j
++) {
585 write(tmp_fd
, buf
, sizeof(buf
));
587 retval
= fsync(tmp_fd
);
589 T_ASSERT_POSIX_SUCCESS(retval
, "file fsync()");
591 map_tmp
= mmap(0, PAGE_SIZE
, PROT_WRITE
, MAP_PRIVATE
, tmp_fd
, (off_t
)PAGE_SIZE
);
592 T_ASSERT_NE_PTR(map_tmp
, MAP_FAILED
, "mmap() for PROC_PIDREGIONINFO");
594 T_LOG("file: %s is opened as fd %d and mapped at %llx with size %lu", CONF_TMP_FILE_PATH
, tmp_fd
, (uint64_t)map_tmp
,
595 (unsigned long)PAGE_SIZE
);
598 if (proc_info_opts
& PREGINFO
) {
599 PROC_INFO_CALL(proc_regioninfo
, getpid(), PROC_PIDREGIONINFO
, map_tmp
);
600 ret_structs
[i
] = map_tmp
;
603 if (proc_info_opts
& PREGINFO_PATH
) {
604 PROC_INFO_CALL(proc_regionwithpathinfo
, getpid(), PROC_PIDREGIONPATHINFO
, map_tmp
);
605 ret_structs
[i
] = map_tmp
;
608 if (proc_info_opts
& PREGINFO_PATH_2
) {
609 PROC_INFO_CALL(proc_regionwithpathinfo
, getpid(), PROC_PIDREGIONPATHINFO2
, map_tmp
);
610 ret_structs
[i
] = map_tmp
;
614 if (proc_info_opts
& PREGINFO_PATH_3
) {
615 struct proc_regionwithpathinfo
* preginfo_path
= malloc(sizeof(struct proc_regionwithpathinfo
));
617 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, getpid(), PROC_PIDREGIONPATHINFO2
, (uint64_t)map_tmp
,
618 (user_addr_t
)preginfo_path
, (uint32_t)sizeof(struct proc_regionwithpathinfo
));
620 T_ASSERT_EQ_INT(retval
, (int)sizeof(struct proc_regionwithpathinfo
), "__proc_info call for PROC_PIDREGIONPATHINFO2");
622 T_LOG("preginfo_path.prp_vip.vip_vi.vi_fsid.val 0: %d", preginfo_path
->prp_vip
.vip_vi
.vi_fsid
.val
[0]);
623 T_LOG("preginfo_path.prp_vip.vip_vi.vi_fsid.val 1: %d", preginfo_path
->prp_vip
.vip_vi
.vi_fsid
.val
[1]);
625 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, getpid(), PROC_PIDREGIONPATHINFO3
,
626 (uint64_t)(*(uint32_t *)(preginfo_path
->prp_vip
.vip_vi
.vi_fsid
.val
)), (user_addr_t
)preginfo_path
,
627 (uint32_t)sizeof(struct proc_regionwithpathinfo
));
628 T_ASSERT_EQ_INT(retval
, (int)sizeof(struct proc_regionwithpathinfo
), "__proc_info call for PROC_PIDREGIONPATHWITHINFO3");
629 ret_structs
[i
] = (void *)preginfo_path
;
633 if (proc_info_opts
& PVNINFO
) {
634 PROC_INFO_CALL(proc_vnodepathinfo
, getpid(), PROC_PIDVNODEPATHINFO
, 0);
637 kill_child_processes(proc_config
);
638 free_proc_config(proc_config
);
646 free_proc_info(void ** proc_info
, int num
)
648 for (int i
= 0; i
< num
; i
++) {
659 T_DECL(proc_info_listpids_all_pids
,
660 "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
662 T_META_LTEPHASE(LTE_POSTINIT
))
665 * Get the value of nprocs with no buffer sent in
668 num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_ALL_PIDS
, (uint32_t)getpid(), (uint32_t)0, (user_addr_t
)0, (uint32_t)0);
669 T_ASSERT_GE_INT(num_procs
, 1, "verify valid value for nprocs: %d", num_procs
);
671 proc_config_t proc_config
= spawn_child_processes(CONF_PROC_COUNT
, proc_info_listpids_handler
);
673 num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_ALL_PIDS
, (uint32_t)getpid(), (uint32_t)0, (user_addr_t
)0, (uint32_t)0);
675 int proc_count
= num_procs
/ (int)sizeof(pid_t
);
676 int proc_count_all
= num_procs
/ (int)sizeof(pid_t
);
677 if (proc_count
> (CONF_PROC_COUNT
+ 1)) {
678 proc_count
= CONF_PROC_COUNT
+ 1;
680 pid_t
* proc_ids
= malloc(sizeof(pid_t
) * (unsigned long)proc_count
);
681 num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_ALL_PIDS
, (uint32_t)getpid(), (uint32_t)0, (user_addr_t
)proc_ids
,
682 (int32_t)(proc_count
* (int)sizeof(pid_t
)));
683 num_procs
= num_procs
/ (int)sizeof(pid_t
);
684 T_ASSERT_GE_INT(num_procs
, proc_count
, "Valid number of pids obtained for PROC_ALL_PIDS.");
689 * Grab list of all procs and make sure our spawned children are in the list.
692 proc_ids
= malloc(sizeof(pid_t
) * (unsigned long)proc_count_all
);
693 num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_ALL_PIDS
, (uint32_t)getpid(), (uint32_t)0, (user_addr_t
)proc_ids
,
694 (int32_t)(proc_count_all
* (int)sizeof(pid_t
)));
695 num_procs
= num_procs
/ (int)sizeof(pid_t
);
699 for (int i
= 0; i
< (CONF_PROC_COUNT
- 1); i
++) {
700 for (int j
= 0; j
< num_procs
; j
++) {
701 if (proc_ids
[j
] == proc_config
->child_pids
[i
]) {
703 } else if (j
== (num_procs
- 1)) {
714 T_ASSERT_EQ(pid_match
, 1, "PROC_INFO_CALL_LISTPIDS contains our spawned children's pids");
718 kill_child_processes(proc_config
);
719 free_proc_config(proc_config
);
722 num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_ALL_PIDS
, (uint32_t)getpid(), (uint32_t)0, (user_addr_t
)proc_ids
,
723 (uint32_t)(sizeof(pid_t
) - 1));
724 T_EXPECT_POSIX_ERROR(errno
, ENOMEM
, "Valid proc_info behavior when bufsize < sizeof(pid_t).");
727 T_DECL(proc_info_listpids_pgrp_only
,
728 "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
730 T_META_LTEPHASE(LTE_POSTINIT
))
732 proc_config_t proc_config
= spawn_child_processes(CONF_PROC_COUNT
, proc_info_listpids_handler
);
733 T_LOG("Test to verify PROC_PGRP_ONLY returns correct value");
735 * The number of obtained pids depends on size of buffer.
736 * count = childCount + 1(parent)
737 * So, we set it to one more than expected to capture any error.
739 int proc_count
= CONF_PROC_COUNT
+ 2;
740 pid_t
* proc_ids
= malloc(sizeof(*proc_ids
) * (unsigned long)proc_count
);
741 int num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_PGRP_ONLY
, (uint32_t)proc_config
->proc_grp_id
, (uint32_t)0,
742 (user_addr_t
)proc_ids
, (int32_t)(proc_count
* (int)sizeof(*proc_ids
)));
743 num_procs
= num_procs
/ (int)sizeof(pid_t
);
744 T_ASSERT_EQ_INT(num_procs
, CONF_PROC_COUNT
+ 1, "Valid number of pids obtained for PROC_PGRP_ONLY.");
745 kill_child_processes(proc_config
);
746 free_proc_config(proc_config
);
750 T_DECL(proc_info_listpids_ppid_only
,
751 "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
753 T_META_LTEPHASE(LTE_POSTINIT
))
755 proc_config_t proc_config
= spawn_child_processes(CONF_PROC_COUNT
, proc_info_listpids_handler
);
756 T_LOG("Test to verify PROC_PPID_ONLY returns correct value");
758 * Pass in the same (bigger) buffer but expect only the pids where ppid is pid of current proc.
760 int proc_count
= CONF_PROC_COUNT
+ 2;
761 pid_t
* proc_ids
= malloc(sizeof(*proc_ids
) * (unsigned long)proc_count
);
762 int num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_PPID_ONLY
, (uint32_t)getpid(), (uint32_t)0, (user_addr_t
)proc_ids
,
763 (int32_t)(proc_count
* (int)sizeof(*proc_ids
)));
764 num_procs
= num_procs
/ (int)sizeof(pid_t
);
765 T_ASSERT_EQ_INT(num_procs
, CONF_PROC_COUNT
, "Valid number of pids obtained for PROC_PPID_ONLY.");
766 kill_child_processes(proc_config
);
767 free_proc_config(proc_config
);
771 T_DECL(proc_info_listpids_uid_only
,
772 "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
774 T_META_LTEPHASE(LTE_POSTINIT
))
776 proc_config_t proc_config
= spawn_child_processes(CONF_PROC_COUNT
, proc_info_listpids_handler
);
777 T_LOG("Test to verify PROC_UID_ONLY returns correct value");
778 int proc_count
= CONF_PROC_COUNT
+ 2;
779 pid_t
* proc_ids
= malloc(sizeof(*proc_ids
) * (unsigned long)proc_count
);
780 send_action_to_child_processes(proc_config
, ACT_CHANGE_UID
);
782 int num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_UID_ONLY
, CONF_UID_VAL
, (uint32_t)0, (user_addr_t
)proc_ids
,
783 (int32_t)(proc_count
* (int)sizeof(*proc_ids
)));
784 T_ASSERT_GE_ULONG((unsigned long)num_procs
/ sizeof(pid_t
), (unsigned long)CONF_PROC_COUNT
,
785 "Valid number of pids obtained for PROC_UID_ONLY.");
786 kill_child_processes(proc_config
);
787 free_proc_config(proc_config
);
791 T_DECL(proc_info_listpids_ruid_only
,
792 "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
794 T_META_LTEPHASE(LTE_POSTINIT
))
796 proc_config_t proc_config
= spawn_child_processes(CONF_PROC_COUNT
, proc_info_listpids_handler
);
797 T_LOG("Test to verify PROC_RUID_ONLY returns correct value");
798 int proc_count
= CONF_PROC_COUNT
+ 2;
799 pid_t
* proc_ids
= malloc(sizeof(*proc_ids
) * (unsigned long)proc_count
);
800 send_action_to_child_processes(proc_config
, ACT_CHANGE_RUID
);
802 int num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_RUID_ONLY
, CONF_RUID_VAL
, (uint32_t)0, (user_addr_t
)proc_ids
,
803 (int32_t)(proc_count
* (int)sizeof(*proc_ids
)));
804 T_ASSERT_GE_ULONG((unsigned long)num_procs
/ sizeof(pid_t
), (unsigned long)CONF_PROC_COUNT
,
805 "Valid number of pids obtained for PROC_RUID_ONLY.");
806 kill_child_processes(proc_config
);
807 free_proc_config(proc_config
);
811 T_DECL(proc_info_listpids_tty_only
,
812 "proc_info API test to verify PROC_INFO_CALL_LISTPIDS",
814 T_META_LTEPHASE(LTE_POSTINIT
))
816 int ret
= isatty(STDOUT_FILENO
);
818 T_SKIP("Not connected to tty...skipping test");
821 proc_config_t proc_config
= spawn_child_processes(CONF_PROC_COUNT
, proc_info_listpids_handler
);
823 T_LOG("Test to verify PROC_TTY_ONLY returns correct value");
824 int proc_count
= CONF_PROC_COUNT
+ 2;
825 pid_t
* proc_ids
= malloc(sizeof(*proc_ids
) * (unsigned long)proc_count
);
826 int num_procs
= __proc_info(PROC_INFO_CALL_LISTPIDS
, PROC_TTY_ONLY
, get_tty_dev(), (uint32_t)0, (user_addr_t
)proc_ids
,
827 (int32_t)(proc_count
* (int)sizeof(*proc_ids
)));
828 num_procs
= num_procs
/ (int)sizeof(pid_t
);
829 T_ASSERT_GE_INT(num_procs
, 0, "Valid number of pids returned by PROC_TTY_ONLY.");
830 kill_child_processes(proc_config
);
831 free_proc_config(proc_config
);
836 * Most of the following PROC_INFO_CALL_PIDINFO tests rely on a helper function (proc_info_caller) to make the necessary proc_info
837 * calls on their behalf
838 * In a previous iteration, these tests were all in one giant T_DECL and the helper function handles inter-DECL dependencies such as
839 * a proc_info call relying on the results of a previous proc_info call or an assumed state that a child should be in.
842 T_DECL(proc_info_pidinfo_proc_piduniqidentifierinfo
,
843 "Test to identify PROC_PIDUNIQIDENTIFIERINFO returns correct unique identifiers for process",
845 T_META_LTEPHASE(LTE_POSTINIT
))
848 proc_info_caller(P_UNIQIDINFO
| C_UNIQIDINFO
, proc_info
, NULL
);
849 struct proc_uniqidentifierinfo
* p_uniqidinfo
= (struct proc_uniqidentifierinfo
*)proc_info
[0];
850 struct proc_uniqidentifierinfo
* c_uniqidinfo
= (struct proc_uniqidentifierinfo
*)proc_info
[1];
852 T_EXPECT_NE_ULLONG(c_uniqidinfo
->p_uniqueid
, p_uniqidinfo
->p_uniqueid
, "p_uniqueid not unique for the process");
854 for (size_t i
= 0; i
< 16; i
++) {
855 T_EXPECT_EQ_UCHAR(c_uniqidinfo
->p_uuid
[i
], p_uniqidinfo
->p_uuid
[i
], "p_uuid should be the same unique id");
857 T_EXPECT_EQ_ULLONG(c_uniqidinfo
->p_puniqueid
, p_uniqidinfo
->p_uniqueid
,
858 "p_puniqueid of child should be same as p_uniqueid for parent");
860 free_proc_info(proc_info
, 2);
863 T_DECL(proc_info_pidinfo_proc_pidtbsdinfo
,
864 "Test to verify PROC_PIDTBSDINFO returns valid information about the process",
866 T_META_LTEPHASE(LTE_POSTINIT
))
870 proc_info_caller(PBSD_OLD
| PBSD
, proc_info
, &child_pid
);
871 struct proc_bsdinfo
* pbsd_old
= (struct proc_bsdinfo
*)proc_info
[0];
872 struct proc_bsdinfo
* pbsd
= (struct proc_bsdinfo
*)proc_info
[1];
874 T_EXPECT_EQ_UINT((unsigned int)SRUN
, pbsd
->pbi_status
, "PROC_PIDTBSDINFO shows Correct status");
875 T_EXPECT_EQ_UINT(0U, pbsd
->pbi_xstatus
, "PROC_PIDTBSDINFO show Correct xstatus (exit status)");
876 T_EXPECT_EQ_UINT(pbsd
->pbi_pid
, (unsigned int)child_pid
, "PROC_PIDTBSDINFO returns valid pid");
877 T_EXPECT_EQ_UINT(pbsd
->pbi_ppid
, (unsigned int)getpid(), "PROC_PIDTBSDINFO returns valid ppid");
878 T_EXPECT_EQ_UINT(pbsd
->pbi_uid
, CONF_RUID_VAL
, "PROC_PIDTBSDINFO returns valid uid");
879 T_EXPECT_EQ_UINT(pbsd
->pbi_gid
, CONF_GID_VAL
, "PROC_PIDTBSDINFO returns valid gid");
880 T_EXPECT_EQ_UINT(pbsd
->pbi_ruid
, 0U, "PROC_PIDTBSDINFO returns valid ruid");
881 T_EXPECT_EQ_UINT(pbsd
->pbi_rgid
, CONF_GID_VAL
, "PROC_PIDTBSDINFO returns valid rgid");
882 T_EXPECT_EQ_UINT(pbsd
->pbi_svuid
, CONF_RUID_VAL
, "PROC_PIDTBSDINFO returns valid svuid");
883 T_EXPECT_EQ_UINT(pbsd
->pbi_svgid
, CONF_GID_VAL
, "PROC_PIDTBSDINFO returns valid svgid");
884 T_EXPECT_EQ_UINT(pbsd
->pbi_nice
, CONF_NICE_VAL
, "PROC_PIDTBSDINFO returns valid nice value");
885 T_EXPECT_EQ_STR(pbsd
->pbi_comm
, CONF_CMD_NAME
, "PROC_PIDTBSDINFO returns valid p_comm name");
886 T_EXPECT_EQ_STR(pbsd
->pbi_name
, CONF_CMD_NAME
, "PROC_PIDTBSDINFO returns valid p_name name");
887 T_EXPECT_EQ_UINT(pbsd
->pbi_flags
, (pbsd_old
->pbi_flags
| PROC_FLAG_PSUGID
), "PROC_PIDTBSDINFO returns valid flags");
888 T_EXPECT_EQ_UINT(pbsd
->pbi_nfiles
, pbsd_old
->pbi_nfiles
, "PROC_PIDTBSDINFO returned valid pbi_nfiles");
889 T_EXPECT_EQ_UINT(pbsd
->pbi_pgid
, (uint32_t)getpgid(getpid()), "PROC_PIDTBSDINFO returned valid pbi_pgid");
890 T_EXPECT_EQ_UINT(pbsd
->pbi_pjobc
, pbsd
->pbi_pjobc
, "PROC_PIDTBSDINFO returned valid pbi_pjobc");
891 T_EXPECT_NE_UINT(pbsd
->e_tdev
, 0U, "PROC_PIDTBSDINFO returned valid e_tdev");
893 free_proc_info(proc_info
, 2);
896 T_DECL(proc_info_pidt_shortbsdinfo
,
897 "Test to verify PROC_PIDT_SHORTBSDINFO returns valid information about the process",
899 T_META_LTEPHASE(LTE_POSTINIT
))
903 proc_info_caller(PBSD
| PBSD_SHORT
, proc_info
, &child_pid
);
904 struct proc_bsdinfo
* pbsd
= (struct proc_bsdinfo
*)proc_info
[0];
905 struct proc_bsdshortinfo
* pbsd_short
= (struct proc_bsdshortinfo
*)proc_info
[1];
907 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_pid
, (unsigned int)child_pid
, "PROC_PIDT_SHORTBSDINFO returns valid pid");
908 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_ppid
, (unsigned int)getpid(), "PROC_PIDT_SHORTBSDINFO returns valid ppid");
909 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_pgid
, (uint32_t)getpgid(getpid()), "PROC_PIDT_SHORTBSDINFO returned valid pbi_pgid");
910 T_EXPECT_EQ_UINT((unsigned int)SRUN
, pbsd_short
->pbsi_status
, "PROC_PIDT_SHORTBSDINFO shows Correct status");
911 T_EXPECT_EQ_STR(pbsd_short
->pbsi_comm
, CONF_CMD_NAME
, "PROC_PIDT_SHORTBSDINFO returns valid p_comm name");
913 * The short variant returns all flags except session flags, hence ignoring them here.
915 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_flags
, (pbsd
->pbi_flags
& (unsigned int)(~PROC_FLAG_CTTY
)),
916 "PROC_PIDT_SHORTBSDINFO returns valid flags");
917 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_uid
, CONF_RUID_VAL
, "PROC_PIDT_SHORTBSDINFO returns valid uid");
918 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_gid
, CONF_GID_VAL
, "PROC_PIDT_SHORTBSDINFO returns valid gid");
919 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_ruid
, 0U, "PROC_PIDT_SHORTBSDINFO returns valid ruid");
920 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_svuid
, CONF_RUID_VAL
, "PROC_PIDT_SHORTBSDINFO returns valid svuid");
921 T_EXPECT_EQ_UINT(pbsd_short
->pbsi_svgid
, CONF_GID_VAL
, "PROC_PIDT_SHORTBSDINFO returns valid svgid");
923 free_proc_info(proc_info
, 2);
926 T_DECL(proc_info_pidt_bsdinfowithuniqid
,
927 "Test to verify PROC_PIDT_BSDINFOWITHUNIQID returns valid information about the process",
929 T_META_LTEPHASE(LTE_POSTINIT
))
933 proc_info_caller(P_UNIQIDINFO
| PBSD_OLD
| PBSD
| PBSD_UNIQID
, proc_info
, &child_pid
);
934 struct proc_uniqidentifierinfo
* p_uniqidinfo
= (struct proc_uniqidentifierinfo
*)proc_info
[0];
935 struct proc_bsdinfo
* pbsd_old
= (struct proc_bsdinfo
*)proc_info
[1];
936 struct proc_bsdinfo
* pbsd
= (struct proc_bsdinfo
*)proc_info
[2];
937 struct proc_bsdinfowithuniqid
* pbsd_uniqid
= (struct proc_bsdinfowithuniqid
*)proc_info
[3];
939 T_EXPECT_EQ_UINT((unsigned int)SRUN
, pbsd
->pbi_status
, "PROC_PIDT_BSDINFOWITHUNIQID shows Correct status");
940 T_EXPECT_EQ_UINT(0U, pbsd
->pbi_xstatus
, "PROC_PIDT_BSDINFOWITHUNIQID show Correct xstatus");
941 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_pid
, (unsigned int)child_pid
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid pid");
942 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_ppid
, (unsigned int)getpid(), "PROC_PIDT_BSDINFOWITHUNIQID returns valid ppid");
943 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_uid
, CONF_RUID_VAL
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid uid");
944 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_gid
, CONF_GID_VAL
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid gid");
945 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_ruid
, 0U, "PROC_PIDT_BSDINFOWITHUNIQID returns valid ruid");
946 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_rgid
, CONF_GID_VAL
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid rgid");
947 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_svuid
, CONF_RUID_VAL
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid svuid");
948 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_svgid
, CONF_GID_VAL
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid svgid");
949 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_nice
, CONF_NICE_VAL
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid nice value");
950 T_EXPECT_EQ_STR(pbsd_uniqid
->pbsd
.pbi_comm
, CONF_CMD_NAME
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid p_comm name");
951 T_EXPECT_EQ_STR(pbsd_uniqid
->pbsd
.pbi_name
, CONF_CMD_NAME
, "PROC_PIDT_BSDINFOWITHUNIQID returns valid p_name name");
952 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_flags
, (pbsd_old
->pbi_flags
| PROC_FLAG_PSUGID
),
953 "PROC_PIDT_BSDINFOWITHUNIQID returns valid flags");
954 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_nfiles
, pbsd_old
->pbi_nfiles
, "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_nfiles");
955 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_pgid
, (uint32_t)getpgid(getpid()),
956 "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_pgid");
957 T_EXPECT_EQ_UINT(pbsd_uniqid
->pbsd
.pbi_pjobc
, pbsd
->pbi_pjobc
, "PROC_PIDT_BSDINFOWITHUNIQID returned valid pbi_pjobc");
958 T_EXPECT_NE_UINT(pbsd_uniqid
->pbsd
.e_tdev
, 0U, "PROC_PIDT_BSDINFOWITHUNIQID returned valid e_tdev");
959 T_EXPECT_NE_ULLONG(pbsd_uniqid
->p_uniqidentifier
.p_uniqueid
, p_uniqidinfo
->p_uniqueid
,
960 "PROC_PIDT_BSDINFOWITHUNIQID returned valid p_uniqueid");
961 for (int i
= 0; i
< 16; i
++) {
962 T_EXPECT_EQ_UCHAR(pbsd_uniqid
->p_uniqidentifier
.p_uuid
[i
], p_uniqidinfo
->p_uuid
[i
],
963 "PROC_PIDT_BSDINFOWITHUNIQID reported valid p_uniqueid");
965 T_EXPECT_EQ_ULLONG(pbsd_uniqid
->p_uniqidentifier
.p_puniqueid
, p_uniqidinfo
->p_uniqueid
,
966 "p_puniqueid of child should be same as p_uniqueid for parent");
968 free_proc_info(proc_info
, 4);
971 T_DECL(proc_info_proc_pidtask_info
,
972 "Test to verify PROC_PIDTASKINFO returns valid information about the process",
974 T_META_LTEPHASE(LTE_POSTINIT
))
977 proc_info_caller(P_TASK_INFO
| P_TASK_INFO_NEW
, proc_info
, NULL
);
978 struct proc_taskinfo
* p_task_info
= (struct proc_taskinfo
*)proc_info
[0];
979 struct proc_taskinfo
* p_task_info_new
= (struct proc_taskinfo
*)proc_info
[1];
981 T_EXPECT_GE_ULLONG((p_task_info_new
->pti_virtual_size
- p_task_info
->pti_virtual_size
), (unsigned long long)PAGE_SIZE
,
982 "PROC_PIDTASKINFO returned valid value for pti_virtual_size");
983 T_EXPECT_GE_ULLONG((p_task_info_new
->pti_resident_size
- p_task_info
->pti_resident_size
), (unsigned long long)PAGE_SIZE
,
984 "PROC_PIDTASKINFO returned valid value for pti_virtual_size");
985 T_EXPECT_EQ_INT(p_task_info_new
->pti_policy
, POLICY_TIMESHARE
, "PROC_PIDTASKINFO returned valid value for pti_virtual_size");
986 T_EXPECT_GE_ULLONG(p_task_info
->pti_threads_user
, 1ULL, "PROC_PIDTASKINFO returned valid value for pti_threads_user");
987 #if defined(__arm__) || defined(__arm64__)
988 T_EXPECT_GE_ULLONG(p_task_info
->pti_threads_system
, 0ULL, "PROC_PIDTASKINFO returned valid value for pti_threads_system");
989 T_EXPECT_GE_ULLONG((p_task_info_new
->pti_total_system
- p_task_info
->pti_total_system
), 0ULL,
990 "PROC_PIDTASKINFO returned valid value for pti_total_system");
992 T_EXPECT_GE_ULLONG(p_task_info
->pti_threads_system
, 1ULL, "PROC_PIDTASKINFO returned valid value for pti_threads_system");
993 T_EXPECT_GT_ULLONG((p_task_info_new
->pti_total_system
- p_task_info
->pti_total_system
), 0ULL,
994 "PROC_PIDTASKINFO returned valid value for pti_total_system");
996 T_EXPECT_GT_ULLONG((p_task_info_new
->pti_total_user
- p_task_info
->pti_total_user
), 0ULL,
997 "PROC_PIDTASKINFO returned valid value for pti_total_user");
998 T_EXPECT_GE_INT((p_task_info_new
->pti_faults
- p_task_info
->pti_faults
), 1,
999 "PROC_PIDTASKINFO returned valid value for pti_faults");
1000 T_EXPECT_GE_INT((p_task_info_new
->pti_cow_faults
- p_task_info
->pti_cow_faults
), 1,
1001 "PROC_PIDTASKINFO returned valid value for pti_cow_faults");
1002 T_EXPECT_GE_INT((p_task_info_new
->pti_syscalls_mach
- p_task_info
->pti_syscalls_mach
), 0,
1003 "PROC_PIDTASKINFO returned valid value for pti_syscalls_mach");
1004 T_EXPECT_GE_INT((p_task_info_new
->pti_syscalls_unix
- p_task_info
->pti_syscalls_unix
), 2,
1005 "PROC_PIDTASKINFO returned valid value for pti_syscalls_unix");
1006 T_EXPECT_EQ_INT((p_task_info_new
->pti_messages_sent
- p_task_info
->pti_messages_sent
), 0,
1007 "PROC_PIDTASKINFO returned valid value for pti_messages_sent");
1008 T_EXPECT_EQ_INT((p_task_info_new
->pti_messages_received
- p_task_info
->pti_messages_received
), 0,
1009 "PROC_PIDTASKINFO returned valid value for pti_messages_received");
1010 T_EXPECT_EQ_INT(p_task_info_new
->pti_priority
, p_task_info
->pti_priority
,
1011 "PROC_PIDTASKINFO returned valid value for pti_priority");
1012 T_EXPECT_GE_INT(p_task_info_new
->pti_threadnum
, 1, "PROC_PIDTASKINFO returned valid value for pti_threadnum");
1014 if (p_task_info_new
->pti_threadnum
> 1) {
1015 T_LOG("WARN: PROC_PIDTASKINFO returned threadnum greater than 1");
1017 T_EXPECT_GE_INT(p_task_info_new
->pti_numrunning
, 0, "PROC_PIDTASKINFO returned valid value for pti_numrunning");
1018 T_EXPECT_GE_INT(p_task_info_new
->pti_pageins
, 0, "PROC_PIDTASKINFO returned valid value for pti_pageins");
1020 if (p_task_info_new
->pti_pageins
> 0) {
1021 T_LOG("WARN: PROC_PIDTASKINFO returned pageins greater than 0");
1024 T_EXPECT_GE_INT(p_task_info_new
->pti_csw
, p_task_info
->pti_csw
, "PROC_PIDTASKINFO returned valid value for pti_csw");
1026 free_proc_info(proc_info
, 2);
1029 T_DECL(proc_info_proc_pidtaskallinfo
,
1030 "Test to verify PROC_PIDTASKALLINFO returns valid information about the process",
1031 T_META_ASROOT(true),
1032 T_META_LTEPHASE(LTE_POSTINIT
))
1034 void * proc_info
[4];
1036 proc_info_caller(PBSD
| PBSD_OLD
| P_TASK_INFO
| PALL
, proc_info
, &child_pid
);
1037 struct proc_bsdinfo
* pbsd
= (struct proc_bsdinfo
*)proc_info
[0];
1038 struct proc_bsdinfo
* pbsd_old
= (struct proc_bsdinfo
*)proc_info
[1];
1039 struct proc_taskinfo
* p_task_info
= (struct proc_taskinfo
*)proc_info
[2];
1040 struct proc_taskallinfo
* pall
= (struct proc_taskallinfo
*)proc_info
[3];
1042 T_EXPECT_EQ_UINT((unsigned int)SRUN
, pbsd
->pbi_status
, "PROC_PIDTASKALLINFO shows Correct status");
1043 T_EXPECT_EQ_UINT(0U, pbsd
->pbi_xstatus
, "PROC_PIDTASKALLINFO show Correct xstatus");
1044 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_pid
, (unsigned int)child_pid
, "PROC_PIDTASKALLINFO returns valid pid");
1045 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_ppid
, (unsigned int)getpid(), "PROC_PIDTASKALLINFO returns valid ppid");
1046 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_uid
, CONF_RUID_VAL
, "PROC_PIDTASKALLINFO returns valid uid");
1047 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_gid
, CONF_GID_VAL
, "PROC_PIDTASKALLINFO returns valid gid");
1048 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_ruid
, 0U, "PROC_PIDTASKALLINFO returns valid ruid");
1049 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_rgid
, CONF_GID_VAL
, "PROC_PIDTASKALLINFO returns valid rgid");
1050 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_svuid
, CONF_RUID_VAL
, "PROC_PIDTASKALLINFO returns valid svuid");
1051 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_svgid
, CONF_GID_VAL
, "PROC_PIDTASKALLINFO returns valid svgid");
1052 T_EXPECT_EQ_INT(pall
->pbsd
.pbi_nice
, CONF_NICE_VAL
, "PROC_PIDTASKALLINFO returns valid nice value");
1053 T_EXPECT_EQ_STR(pall
->pbsd
.pbi_comm
, CONF_CMD_NAME
, "PROC_PIDTASKALLINFO returns valid p_comm name");
1054 T_EXPECT_EQ_STR(pall
->pbsd
.pbi_name
, CONF_CMD_NAME
, "PROC_PIDTASKALLINFO returns valid p_name name");
1055 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_flags
, (pbsd_old
->pbi_flags
| PROC_FLAG_PSUGID
), "PROC_PIDTASKALLINFO returns valid flags");
1056 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_nfiles
, pbsd_old
->pbi_nfiles
, "PROC_PIDTASKALLINFO returned valid pbi_nfiles");
1057 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_pgid
, (uint32_t)getpgid(getpid()), "PROC_PIDTASKALLINFO returned valid pbi_pgid");
1058 T_EXPECT_EQ_UINT(pall
->pbsd
.pbi_pjobc
, pbsd
->pbi_pjobc
, "PROC_PIDTASKALLINFO returned valid pbi_pjobc");
1059 T_EXPECT_NE_UINT(pall
->pbsd
.e_tdev
, 0U, "PROC_PIDTASKALLINFO returned valid e_tdev");
1061 #if defined(__arm__) || defined(__arm64__)
1062 T_EXPECT_GE_ULLONG(pall
->ptinfo
.pti_threads_system
, 0ULL, "PROC_PIDTASKALLINFO returned valid value for pti_threads_system");
1063 T_EXPECT_GE_ULLONG((pall
->ptinfo
.pti_total_system
- p_task_info
->pti_total_system
), 0ULL,
1064 "PROC_PIDTASKALLINFO returned valid value for pti_total_system");
1066 T_EXPECT_GE_ULLONG(pall
->ptinfo
.pti_threads_system
, 1ULL, "PROC_PIDTASKALLINFO returned valid value for pti_threads_system");
1067 T_EXPECT_GT_ULLONG((pall
->ptinfo
.pti_total_system
- p_task_info
->pti_total_system
), 0ULL,
1068 "PROC_PIDTASKALLINFO returned valid value for pti_total_system");
1071 T_EXPECT_GE_ULLONG((pall
->ptinfo
.pti_virtual_size
- p_task_info
->pti_virtual_size
), (unsigned long long)PAGE_SIZE
,
1072 "PROC_PIDTASKALLINFO returned valid value for pti_virtual_size");
1073 T_EXPECT_GE_ULLONG((pall
->ptinfo
.pti_resident_size
- p_task_info
->pti_resident_size
), (unsigned long long)PAGE_SIZE
,
1074 "PROC_PIDTASKALLINFO returned valid value for pti_virtual_size");
1075 T_EXPECT_EQ_INT(pall
->ptinfo
.pti_policy
, POLICY_TIMESHARE
, "PROC_PIDTASKALLINFO returned valid value for pti_virtual_size");
1076 T_EXPECT_GE_ULLONG(pall
->ptinfo
.pti_threads_user
, 1ULL, "PROC_PIDTASKALLINFO returned valid value for pti_threads_user ");
1077 T_EXPECT_GT_ULLONG((pall
->ptinfo
.pti_total_user
- p_task_info
->pti_total_user
), 0ULL,
1078 "PROC_PIDTASKALLINFO returned valid value for pti_total_user");
1079 T_EXPECT_GE_INT((pall
->ptinfo
.pti_faults
- p_task_info
->pti_faults
), 1,
1080 "PROC_PIDTASKALLINFO returned valid value for pti_faults");
1081 T_EXPECT_GE_INT((pall
->ptinfo
.pti_cow_faults
- p_task_info
->pti_cow_faults
), 1,
1082 "PROC_PIDTASKALLINFO returned valid value for pti_cow_faults");
1083 T_EXPECT_GE_INT((pall
->ptinfo
.pti_syscalls_mach
- p_task_info
->pti_syscalls_mach
), 0,
1084 "PROC_PIDTASKALLINFO returned valid value for pti_syscalls_mach");
1085 T_EXPECT_GE_INT((pall
->ptinfo
.pti_syscalls_unix
- p_task_info
->pti_syscalls_unix
), 2,
1086 "PROC_PIDTASKALLINFO returned valid value for pti_syscalls_unix");
1087 T_EXPECT_EQ_INT((pall
->ptinfo
.pti_messages_sent
- p_task_info
->pti_messages_sent
), 0,
1088 "PROC_PIDTASKALLINFO returned valid value for pti_messages_sent");
1089 T_EXPECT_EQ_INT((pall
->ptinfo
.pti_messages_received
- p_task_info
->pti_messages_received
), 0,
1090 "PROC_PIDTASKALLINFO returned valid value for pti_messages_received");
1091 T_EXPECT_EQ_INT(pall
->ptinfo
.pti_priority
, p_task_info
->pti_priority
,
1092 "PROC_PIDTASKALLINFO returned valid value for pti_priority");
1093 T_EXPECT_GE_INT(pall
->ptinfo
.pti_threadnum
, 1, "PROC_PIDTASKALLINFO returned valid value for pti_threadnum");
1094 if (pall
->ptinfo
.pti_threadnum
> 1) {
1095 T_LOG("WARN: PROC_PIDTASKALLINFO returned threadnum greater than 1");
1097 T_EXPECT_GE_INT(pall
->ptinfo
.pti_numrunning
, 0, "PROC_PIDTASKALLINFO returned valid value for pti_numrunning");
1098 T_EXPECT_GE_INT(pall
->ptinfo
.pti_pageins
, 0, "PROC_PIDTASKALLINFO returned valid value for pti_pageins");
1099 if (pall
->ptinfo
.pti_pageins
> 0) {
1100 T_LOG("WARN: PROC_PIDTASKALLINFO returned pageins greater than 0");
1102 T_EXPECT_GE_INT(pall
->ptinfo
.pti_csw
, p_task_info
->pti_csw
, "PROC_PIDTASKALLINFO returned valid value for pti_csw");
1104 free_proc_info(proc_info
, 4);
1107 T_DECL(proc_info_proc_pidlistthreads
,
1108 "Test to verify PROC_PIDLISTTHREADS returns valid information about process",
1109 T_META_ASROOT(true),
1110 T_META_LTEPHASE(LTE_POSTINIT
))
1112 void * proc_info
[1];
1113 proc_info_caller(THREAD_ADDR
, proc_info
, NULL
);
1116 T_DECL(proc_info_proc_pidthreadinfo
,
1117 "Test to verify PROC_PIDTHREADINFO returns valid information about the process",
1118 T_META_ASROOT(true),
1119 T_META_LTEPHASE(LTE_POSTINIT
))
1121 void * proc_info
[2];
1123 proc_info_caller(PTHINFO_OLD
| PTHINFO
, proc_info
, &child_pid
);
1124 struct proc_threadinfo
* pthinfo_old
= (struct proc_threadinfo
*)proc_info
[0];
1125 struct proc_threadinfo
* pthinfo
= (struct proc_threadinfo
*)proc_info
[1];
1127 T_EXPECT_GT_ULLONG((pthinfo
->pth_user_time
- pthinfo_old
->pth_user_time
), 0ULL,
1128 "PROC_PIDTHREADINFO returns valid value for pth_user_time");
1129 T_EXPECT_GE_ULLONG((pthinfo
->pth_system_time
- pthinfo_old
->pth_system_time
), 0ULL,
1130 "PROC_PIDTHREADINFO returns valid value for pth_system_time");
1132 * This is the scaled cpu usage percentage, since we are not
1133 * doing a really long CPU bound task, it is (nearly) zero
1135 T_EXPECT_GE_INT(pthinfo
->pth_cpu_usage
, 0, "PROC_PIDTHREADINFO returns valid value for pth_cpu_usage");
1136 T_EXPECT_EQ_INT(pthinfo
->pth_policy
, POLICY_TIMESHARE
, "PROC_PIDTHREADINFO returns valid value for pth_policy");
1137 if (!(pthinfo
->pth_run_state
== TH_STATE_WAITING
) && !(pthinfo
->pth_run_state
== TH_STATE_RUNNING
)) {
1138 T_EXPECT_EQ_INT(pthinfo
->pth_run_state
, -1, "PROC_PIDTHREADINFO returns valid value for pth_run_state");
1141 * This value is hardcoded to 0 in the source, hence it will always
1142 * unconditionally return 0
1144 T_EXPECT_EQ_INT(pthinfo
->pth_sleep_time
, 0, "PROC_PIDTHREADINFO returns valid value for pth_sleep_time");
1145 T_EXPECT_LE_INT(pthinfo
->pth_curpri
, (BASEPRI_DEFAULT
- CONF_NICE_VAL
),
1146 "PROC_PIDTHREADINFO returns valid value for pth_curpri");
1147 T_EXPECT_EQ_INT(pthinfo
->pth_priority
, (BASEPRI_DEFAULT
- CONF_NICE_VAL
),
1148 "PROC_PIDTHREADINFO returns valid value for pth_priority");
1149 T_EXPECT_EQ_INT(pthinfo
->pth_maxpriority
, MAXPRI_USER
, "PROC_PIDTHREADINFO returns valid value for pth_maxpriority");
1150 T_EXPECT_EQ_STR(pthinfo
->pth_name
, CONF_THREAD_NAME
, "PROC_PIDTHREADINFO returns valid value for pth_name");
1152 free_proc_info(proc_info
, 2);
1155 T_DECL(proc_info_proc_threadid64info
,
1156 "Test to verify PROC_PIDTHREADID64INFO returns valid information about the process",
1157 T_META_ASROOT(true),
1158 T_META_LTEPHASE(LTE_POSTINIT
))
1160 void * proc_info
[2];
1161 proc_info_caller(PTHINFO
| PTHINFO_64
, proc_info
, NULL
);
1162 struct proc_threadinfo pthinfo
= *((struct proc_threadinfo
*)proc_info
[0]);
1163 struct proc_threadinfo pthinfo_64
= *((struct proc_threadinfo
*)proc_info
[1]);
1164 T_EXPECT_GE_ULLONG(pthinfo_64
.pth_user_time
, pthinfo
.pth_user_time
,
1165 "PROC_PIDTHREADID64INFO returns valid value for pth_user_time");
1166 T_EXPECT_GE_ULLONG(pthinfo_64
.pth_system_time
, pthinfo
.pth_system_time
,
1167 "PROC_PIDTHREADID64INFO returns valid value for pth_system_time");
1168 T_EXPECT_GE_INT(pthinfo_64
.pth_cpu_usage
, pthinfo
.pth_cpu_usage
,
1169 "PROC_PIDTHREADID64INFO returns valid value for pth_cpu_usage");
1170 T_EXPECT_EQ_INT(pthinfo_64
.pth_policy
, POLICY_TIMESHARE
, "PROC_PIDTHREADID64INFO returns valid value for pth_policy");
1171 if (!(pthinfo_64
.pth_run_state
== TH_STATE_WAITING
) && !(pthinfo_64
.pth_run_state
== TH_STATE_RUNNING
)) {
1172 T_EXPECT_EQ_INT(pthinfo_64
.pth_run_state
, -1, "PROC_PIDTHREADID64INFO returns valid value for pth_run_state");
1174 T_EXPECT_EQ_INT(pthinfo_64
.pth_sleep_time
, 0, "PROC_PIDTHREADID64INFO returns valid value for pth_sleep_time");
1175 T_EXPECT_EQ_INT(pthinfo_64
.pth_curpri
, pthinfo
.pth_curpri
, "PROC_PIDTHREADID64INFO returns valid value for pth_curpri");
1176 T_EXPECT_EQ_INT(pthinfo_64
.pth_priority
, pthinfo
.pth_priority
, "PROC_PIDTHREADID64INFO returns valid value for pth_priority");
1177 T_EXPECT_EQ_INT(pthinfo_64
.pth_maxpriority
, pthinfo
.pth_maxpriority
,
1178 "PROC_PIDTHREADID64INFO returns valid value for pth_maxpriority");
1179 T_EXPECT_EQ_STR(pthinfo_64
.pth_name
, CONF_THREAD_NAME
, "PROC_PIDTHREADID64INFO returns valid value for pth_name");
1181 free_proc_info(proc_info
, 2);
1184 T_DECL(proc_info_proc_pidthreadpathinfo
,
1185 "Test to verify PROC_PIDTHREADPATHINFO returns valid information about the process",
1186 T_META_ASROOT(true),
1187 T_META_LTEPHASE(LTE_POSTINIT
))
1189 void * proc_info
[2];
1190 proc_info_caller(PTHINFO
| PINFO_PATH
, proc_info
, NULL
);
1191 struct proc_threadinfo pthinfo
= *((struct proc_threadinfo
*)proc_info
[0]);
1192 struct proc_threadwithpathinfo pinfo_path
= *((struct proc_threadwithpathinfo
*)proc_info
[1]);
1194 T_EXPECT_GE_ULLONG(pinfo_path
.pt
.pth_user_time
, pthinfo
.pth_user_time
,
1195 "PROC_PIDTHREADPATHINFO returns valid value for pth_user_time");
1196 T_EXPECT_GE_ULLONG(pinfo_path
.pt
.pth_system_time
, pthinfo
.pth_system_time
,
1197 "PROC_PIDTHREADPATHINFO returns valid value for pth_system_time");
1198 T_EXPECT_GE_INT(pinfo_path
.pt
.pth_cpu_usage
, pthinfo
.pth_cpu_usage
,
1199 "PROC_PIDTHREADPATHINFO returns valid value for pth_cpu_usage");
1200 T_EXPECT_EQ_INT(pinfo_path
.pt
.pth_policy
, POLICY_TIMESHARE
, "PROC_PIDTHREADPATHINFO returns valid value for pth_policy");
1201 if (!(pinfo_path
.pt
.pth_run_state
== TH_STATE_WAITING
) && !(pinfo_path
.pt
.pth_run_state
== TH_STATE_RUNNING
)) {
1202 T_EXPECT_EQ_INT(pinfo_path
.pt
.pth_run_state
, -1, "PROC_PIDTHREADPATHINFO returns valid value for pth_run_state");
1204 T_EXPECT_EQ_INT(pinfo_path
.pt
.pth_sleep_time
, 0, "PROC_PIDTHREADPATHINFO returns valid value for pth_sleep_time");
1205 T_EXPECT_EQ_INT(pinfo_path
.pt
.pth_curpri
, pthinfo
.pth_curpri
, "PROC_PIDTHREADPATHINFO returns valid value for pth_curpri");
1206 T_EXPECT_EQ_INT(pinfo_path
.pt
.pth_priority
, pthinfo
.pth_priority
,
1207 "PROC_PIDTHREADPATHINFO returns valid value for pth_priority");
1208 T_EXPECT_EQ_INT(pinfo_path
.pt
.pth_maxpriority
, pthinfo
.pth_maxpriority
,
1209 "PROC_PIDTHREADPATHINFO returns valid value for pth_maxpriority");
1210 T_EXPECT_EQ_STR(pinfo_path
.pt
.pth_name
, CONF_THREAD_NAME
, "PROC_PIDTHREADPATHINFO returns valid value for pth_name");
1211 T_EXPECT_EQ_INT(pinfo_path
.pvip
.vip_vi
.vi_type
, VNON
, "PROC_PIDTHREADPATHINFO valid vnode information");
1213 free_proc_info(proc_info
, 2);
1216 T_DECL(proc_info_proc_pidarchinfo
,
1217 "Test to verify PROC_PIDARCHINFO returns valid information about the process",
1218 T_META_ASROOT(true),
1219 T_META_LTEPHASE(LTE_POSTINIT
))
1221 void * proc_info
[1];
1222 proc_info_caller(PAI
, proc_info
, NULL
);
1223 struct proc_archinfo pai
= *((struct proc_archinfo
*)proc_info
[0]);
1225 #if defined(__arm__) || defined(__arm64__)
1226 if (!((pai
.p_cputype
& CPU_TYPE_ARM
) == CPU_TYPE_ARM
) && !((pai
.p_cputype
& CPU_TYPE_ARM64
) == CPU_TYPE_ARM64
)) {
1227 T_EXPECT_EQ_INT(pai
.p_cputype
, CPU_TYPE_ARM
, "PROC_PIDARCHINFO returned valid value for p_cputype");
1229 T_EXPECT_EQ_INT((pai
.p_cpusubtype
& CPU_SUBTYPE_ARM_ALL
), CPU_SUBTYPE_ARM_ALL
,
1230 "PROC_PIDARCHINFO returned valid value for p_cpusubtype");
1232 if (!((pai
.p_cputype
& CPU_TYPE_X86
) == CPU_TYPE_X86
) && !((pai
.p_cputype
& CPU_TYPE_X86_64
) == CPU_TYPE_X86_64
)) {
1233 T_EXPECT_EQ_INT(pai
.p_cputype
, CPU_TYPE_X86
, "PROC_PIDARCHINFO returned valid value for p_cputype");
1236 free_proc_info(proc_info
, 1);
1239 T_DECL(proc_info_proc_pidregioninfo
,
1240 "Test to verify PROC_PIDREGIONINFO returns valid information about the process",
1241 T_META_ASROOT(true),
1242 T_META_LTEPHASE(LTE_POSTINIT
))
1244 void * proc_info
[2];
1245 void * map_tmp
= NULL
;
1246 proc_info_caller(PREGINFO
, proc_info
, NULL
);
1248 struct proc_regioninfo preginfo
= *((struct proc_regioninfo
*)proc_info
[0]);
1250 * map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
1252 map_tmp
= proc_info
[1];
1254 T_EXPECT_EQ_ULLONG(preginfo
.pri_offset
, (unsigned long long)PAGE_SIZE
, "PROC_PIDREGIONINFO returns valid value for pri_offset");
1255 T_EXPECT_EQ_UINT((preginfo
.pri_protection
^ (VM_PROT_READ
| VM_PROT_WRITE
)), 0U,
1256 "PROC_PIDREGIONINFO returns valid value for pri_protection, expected read/write only");
1257 T_EXPECT_EQ_UINT((preginfo
.pri_max_protection
& (VM_PROT_READ
| VM_PROT_WRITE
)), (unsigned int)(VM_PROT_READ
| VM_PROT_WRITE
),
1258 "PROC_PIDREGIONINFO returns valid value for pri_max_protection");
1259 T_EXPECT_EQ_UINT((preginfo
.pri_inheritance
^ VM_INHERIT_COPY
), 0U,
1260 "PROC_PIDREGIONINFO returns valid value for pri_inheritance");
1261 T_EXPECT_EQ_UINT((preginfo
.pri_behavior
^ VM_BEHAVIOR_DEFAULT
), 0U, "PROC_PIDREGIONINFO returns valid value for pri_behavior");
1262 T_EXPECT_EQ_UINT(preginfo
.pri_user_wired_count
, 0U, "PROC_PIDREGIONINFO returns valid value for pri_user_wired_count");
1263 T_EXPECT_EQ_UINT(preginfo
.pri_user_tag
, 0U, "PROC_PIDREGIONINFO returns valid value for pri_user_tag");
1264 T_EXPECT_NE_UINT((preginfo
.pri_flags
^ (PROC_REGION_SUBMAP
| PROC_REGION_SHARED
)), 0U,
1265 "PROC_PIDREGIONINFO returns valid value for pri_flags");
1266 T_EXPECT_EQ_UINT(preginfo
.pri_pages_resident
, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_resident");
1267 T_EXPECT_EQ_UINT(preginfo
.pri_pages_shared_now_private
, 0U,
1268 "PROC_PIDREGIONINFO returns valid value for pri_pages_shared_now_private");
1269 T_EXPECT_EQ_UINT(preginfo
.pri_pages_swapped_out
, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_swapped_out");
1270 T_EXPECT_EQ_UINT(preginfo
.pri_pages_dirtied
, 0U, "PROC_PIDREGIONINFO returns valid value for pri_pages_dirtied");
1271 T_EXPECT_EQ_UINT(preginfo
.pri_ref_count
, 2U, "PROC_PIDREGIONINFO returns valid value for pri_ref_count");
1272 T_EXPECT_EQ_UINT(preginfo
.pri_shadow_depth
, 1U, "PROC_PIDREGIONINFO returns valid value for pri_shadow_depth");
1273 T_EXPECT_EQ_UINT(preginfo
.pri_share_mode
, (unsigned int)SM_COW
, "PROC_PIDREGIONINFO returns valid value for pri_share_mode");
1274 T_EXPECT_EQ_UINT(preginfo
.pri_private_pages_resident
, 0U,
1275 "PROC_PIDREGIONINFO returns valid value for pri_private_pages_resident");
1276 T_EXPECT_GE_UINT(preginfo
.pri_shared_pages_resident
, 1U,
1277 "PROC_PIDREGIONINFO returns valid value for pri_shared_pages_resident");
1278 T_EXPECT_EQ_ULLONG(preginfo
.pri_address
, (uint64_t)map_tmp
, "PROC_PIDREGIONINFO returns valid value for pri_addr");
1279 T_EXPECT_NE_UINT(preginfo
.pri_obj_id
, 0U, "PROC_PIDREGIONINFO returns valid value for pri_obj_id");
1280 T_EXPECT_EQ_ULLONG(preginfo
.pri_size
, (unsigned long long)PAGE_SIZE
, "PROC_PIDREGIONINFO returns valid value for pri_size");
1281 T_EXPECT_EQ_UINT(preginfo
.pri_depth
, 0U, "PROC_PIDREGIONINFO returns valid value for pri_depth");
1284 ret
= munmap(map_tmp
, PAGE_SIZE
);
1286 T_EXPECT_POSIX_SUCCESS(ret
, "munmap of map_tmp");
1287 free_proc_info(proc_info
, 1);
1290 T_DECL(proc_info_proc_pidregionpathinfo
,
1291 "Test to verify PROC_PIDREGIONPATHINFO returns valid information about the process",
1292 T_META_ASROOT(true),
1293 T_META_LTEPHASE(LTE_INSTALLEDUSEROS
))
1295 void * proc_info
[2];
1296 void * map_tmp
= NULL
;
1297 proc_info_caller(PREGINFO_PATH
, proc_info
, NULL
);
1299 struct proc_regionwithpathinfo preginfo_path
= *((struct proc_regionwithpathinfo
*)proc_info
[0]);
1301 * map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
1303 map_tmp
= proc_info
[1];
1305 T_EXPECT_EQ_ULLONG(preginfo_path
.prp_prinfo
.pri_offset
, (uint64_t)PAGE_SIZE
,
1306 "PROC_PIDREGIONPATHINFO returns valid value for pri_offset");
1307 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_protection
^ (VM_PROT_READ
| VM_PROT_WRITE
)), 0U,
1308 "PROC_PIDREGIONPATHINFO returns valid value for pri_protection, expected read/write only");
1309 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_max_protection
& (VM_PROT_READ
| VM_PROT_WRITE
)),
1310 (unsigned int)(VM_PROT_READ
| VM_PROT_WRITE
),
1311 "PROC_PIDREGIONPATHINFO returns valid value for pri_max_protection");
1312 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_inheritance
^ VM_INHERIT_COPY
), 0U,
1313 "PROC_PIDREGIONPATHINFO returns valid value for pri_inheritance");
1314 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_behavior
^ VM_BEHAVIOR_DEFAULT
), 0U,
1315 "PROC_PIDREGIONPATHINFO returns valid value for pri_behavior");
1316 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_user_wired_count
, 0U,
1317 "PROC_PIDREGIONPATHINFO returns valid value for pri_user_wired_count");
1318 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_user_tag
, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_user_tag");
1319 T_EXPECT_NE_UINT((preginfo_path
.prp_prinfo
.pri_flags
^ (PROC_REGION_SUBMAP
| PROC_REGION_SHARED
)), 0U,
1320 "PROC_PIDREGIONPATHINFO returns valid value for pri_flags");
1321 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_resident
, 0U,
1322 "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_resident");
1323 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_shared_now_private
, 0U,
1324 "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_shared_now_private");
1325 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_swapped_out
, 0U,
1326 "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_swapped_out");
1327 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_dirtied
, 0U,
1328 "PROC_PIDREGIONPATHINFO returns valid value for pri_pages_dirtied");
1329 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_ref_count
, 2U, "PROC_PIDREGIONPATHINFO returns valid value for pri_ref_count");
1330 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_shadow_depth
, 1U,
1331 "PROC_PIDREGIONPATHINFO returns valid value for pri_shadow_depth");
1332 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_share_mode
, (unsigned int)SM_COW
,
1333 "PROC_PIDREGIONPATHINFO returns valid value for pri_share_mode");
1334 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_private_pages_resident
, 0U,
1335 "PROC_PIDREGIONPATHINFO returns valid value for pri_private_pages_resident");
1336 T_EXPECT_GE_UINT(preginfo_path
.prp_prinfo
.pri_shared_pages_resident
, 1U,
1337 "PROC_PIDREGIONPATHINFO returns valid value for pri_shared_pages_resident");
1338 T_EXPECT_EQ_ULLONG(preginfo_path
.prp_prinfo
.pri_address
, (uint64_t)map_tmp
,
1339 "PROC_PIDREGIONPATHINFO returns valid value for pri_addr");
1340 T_EXPECT_NE_UINT(preginfo_path
.prp_prinfo
.pri_obj_id
, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_obj_id");
1341 T_EXPECT_EQ_ULLONG(preginfo_path
.prp_prinfo
.pri_size
, (uint64_t)PAGE_SIZE
,
1342 "PROC_PIDREGIONPATHINFO returns valid value for pri_size");
1343 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_depth
, 0U, "PROC_PIDREGIONPATHINFO returns valid value for pri_depth");
1344 T_EXPECT_EQ_INT(preginfo_path
.prp_vip
.vip_vi
.vi_type
, VREG
, "PROC_PIDREGIONPATHINFO returns valid value for vi_type");
1345 T_EXPECT_EQ_INT(preginfo_path
.prp_vip
.vip_vi
.vi_pad
, 0, "PROC_PIDREGIONPATHINFO returns valid value for vi_pad");
1346 T_EXPECT_NE_INT(preginfo_path
.prp_vip
.vip_vi
.vi_fsid
.val
[0], 0,
1347 "PROC_PIDREGIONPATHINFO returns valid value for vi_fsid.val[0]");
1348 T_EXPECT_NE_INT(preginfo_path
.prp_vip
.vip_vi
.vi_fsid
.val
[1], 0,
1349 "PROC_PIDREGIONPATHINFO returns valid value for vi_fsid.val[1]");
1350 T_EXPECT_NE_PTR((void *)(strcasestr(preginfo_path
.prp_vip
.vip_path
, CONF_TMP_FILE_PATH
)), NULL
,
1351 "PROC_PIDREGIONPATHINFO returns valid value for vi_path");
1353 * Basic sanity checks for vnode stat returned by the API
1355 T_EXPECT_NE_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_dev
, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_dev");
1356 T_EXPECT_EQ_INT(((preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_mode
& S_IFMT
) ^ S_IFREG
), 0,
1357 "PROC_PIDREGIONPATHINFO returns valid value for vst_mode");
1358 T_EXPECT_EQ_USHORT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_nlink
, (unsigned short)1,
1359 "PROC_PIDREGIONPATHINFO returns valid value for vst_nlink");
1360 T_EXPECT_NE_ULLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_ino
, 0ULL,
1361 "PROC_PIDREGIONPATHINFO returns valid value for vst_ino");
1362 T_EXPECT_EQ_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_uid
, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_uid");
1363 T_EXPECT_EQ_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_gid
, 0U, "PROC_PIDREGIONPATHINFO returns valid value for vst_gid");
1364 T_EXPECT_GE_LLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_size
, (off_t
)CONF_BLK_SIZE
,
1365 "PROC_PIDREGIONPATHINFO returns valid value for vst_size");
1366 T_EXPECT_GE_LLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_blocks
, 1LL,
1367 "PROC_PIDREGIONPATHINFO returns valid value for vst_blocks");
1368 T_EXPECT_GE_INT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_blksize
, CONF_BLK_SIZE
,
1369 "PROC_PIDREGIONPATHINFO returns valid value for vst_blksize");
1372 ret
= munmap(map_tmp
, PAGE_SIZE
);
1374 T_EXPECT_POSIX_SUCCESS(ret
, "munmap of map_tmp");
1375 free_proc_info(proc_info
, 1);
1378 T_DECL(proc_info_proc_pidregionpathinfo2
,
1379 "Test to verify PROC_PIDREGIONPATHINFO2 returns valid information about the process",
1380 T_META_ASROOT(true),
1381 T_META_LTEPHASE(LTE_INSTALLEDUSEROS
))
1383 void * proc_info
[2];
1384 void * map_tmp
= NULL
;
1385 proc_info_caller(PREGINFO_PATH_2
, proc_info
, NULL
);
1387 struct proc_regionwithpathinfo preginfo_path
= *((struct proc_regionwithpathinfo
*)proc_info
[0]);
1389 * map_tmp isn't a struct like the rest of our ret_structs, but we sneak it back because we need it
1391 map_tmp
= proc_info
[1];
1393 T_EXPECT_EQ_ULLONG(preginfo_path
.prp_prinfo
.pri_offset
, (uint64_t)PAGE_SIZE
,
1394 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_offset");
1395 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_protection
^ (VM_PROT_READ
| VM_PROT_WRITE
)), 0U,
1396 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_protection, expected read/write only");
1397 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_max_protection
& (VM_PROT_READ
| VM_PROT_WRITE
)),
1398 (unsigned int)(VM_PROT_READ
| VM_PROT_WRITE
),
1399 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_max_protection");
1400 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_inheritance
^ VM_INHERIT_COPY
), 0U,
1401 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_inheritance");
1402 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_behavior
^ VM_BEHAVIOR_DEFAULT
), 0U,
1403 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_behavior");
1404 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_user_wired_count
, 0U,
1405 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_user_wired_count");
1406 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_user_tag
, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_user_tag");
1407 T_EXPECT_NE_UINT((preginfo_path
.prp_prinfo
.pri_flags
^ (PROC_REGION_SUBMAP
| PROC_REGION_SHARED
)), 0U,
1408 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_flags");
1410 * Following values are hard-coded to be zero in source
1412 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_resident
, 0U,
1413 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_resident");
1414 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_shared_now_private
, 0U,
1415 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_shared_now_private");
1416 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_swapped_out
, 0U,
1417 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_swapped_out");
1418 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_dirtied
, 0U,
1419 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_pages_dirtied");
1420 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_ref_count
, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_ref_count");
1421 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_shadow_depth
, 0U,
1422 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_shadow_depth");
1423 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_share_mode
, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_share_mode");
1424 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_private_pages_resident
, 0U,
1425 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_private_pages_resident");
1426 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_shared_pages_resident
, 0U,
1427 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_shared_pages_resident");
1428 T_EXPECT_EQ_ULLONG(preginfo_path
.prp_prinfo
.pri_address
, (uint64_t)map_tmp
,
1429 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_addr");
1430 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_obj_id
, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_obj_id");
1431 T_EXPECT_EQ_ULLONG(preginfo_path
.prp_prinfo
.pri_size
, (unsigned long long)PAGE_SIZE
,
1432 "PROC_PIDREGIONPATHINFO2 returns valid value for pri_size");
1433 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_depth
, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for pri_depth");
1435 T_EXPECT_EQ_INT(preginfo_path
.prp_vip
.vip_vi
.vi_type
, VREG
, "PROC_PIDREGIONPATHINFO2 returns valid value for vi_type");
1436 T_EXPECT_EQ_INT(preginfo_path
.prp_vip
.vip_vi
.vi_pad
, 0, "PROC_PIDREGIONPATHINFO2 returns valid value for vi_pad");
1437 T_EXPECT_NE_INT(preginfo_path
.prp_vip
.vip_vi
.vi_fsid
.val
[0], 0,
1438 "PROC_PIDREGIONPATHINFO2 returns valid value for vi_fsid.val[0]:%d",
1439 preginfo_path
.prp_vip
.vip_vi
.vi_fsid
.val
[0]);
1440 T_EXPECT_NE_INT(preginfo_path
.prp_vip
.vip_vi
.vi_fsid
.val
[1], 0,
1441 "PROC_PIDREGIONPATHINFO2 returns valid value for vi_fsid.val[1]:%d",
1442 preginfo_path
.prp_vip
.vip_vi
.vi_fsid
.val
[1]);
1443 T_EXPECT_NE_PTR((void *)(strcasestr(preginfo_path
.prp_vip
.vip_path
, CONF_TMP_FILE_PATH
)), NULL
,
1444 "PROC_PIDREGIONPATHINFO2 returns valid value for vi_path");
1446 * Basic sanity checks for vnode stat returned by the API
1448 T_EXPECT_NE_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_dev
, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_dev");
1449 T_EXPECT_EQ_UINT(((preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_mode
& S_IFMT
) ^ S_IFREG
), 0,
1450 "PROC_PIDREGIONPATHINFO2 returns valid value for vst_mode");
1451 T_EXPECT_EQ_USHORT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_nlink
, (unsigned short)1,
1452 "PROC_PIDREGIONPATHINFO2 returns valid value for vst_nlink");
1453 T_EXPECT_NE_ULLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_ino
, 0ULL,
1454 "PROC_PIDREGIONPATHINFO2 returns valid value for vst_ino");
1455 T_EXPECT_EQ_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_uid
, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_uid");
1456 T_EXPECT_EQ_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_gid
, 0U, "PROC_PIDREGIONPATHINFO2 returns valid value for vst_gid");
1457 T_EXPECT_GE_LLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_size
, (off_t
)CONF_BLK_SIZE
,
1458 "PROC_PIDREGIONPATHINFO2 returns valid value for vst_size");
1459 T_EXPECT_GE_LLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_blocks
, 1LL,
1460 "PROC_PIDREGIONPATHINFO2 returns valid value for vst_blocks");
1461 T_EXPECT_GE_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_blksize
, CONF_BLK_SIZE
,
1462 "PROC_PIDREGIONPATHINFO2 returns valid value for vst_blksize");
1465 ret
= munmap(map_tmp
, PAGE_SIZE
);
1467 T_EXPECT_POSIX_SUCCESS(ret
, "munmap of map_tmp");
1468 free_proc_info(proc_info
, 1);
1471 T_DECL(proc_info_proc_pidregionpathinfo3
,
1472 "Test to verify PROC_PIDREGIONPATHINFO3 returns valid information about the process",
1473 T_META_ASROOT(true),
1474 T_META_LTEPHASE(LTE_INSTALLEDUSEROS
))
1476 void * proc_info
[1];
1477 proc_info_caller(PREGINFO_PATH_3
, proc_info
, NULL
);
1479 struct proc_regionwithpathinfo preginfo_path
= *((struct proc_regionwithpathinfo
*)proc_info
[0]);
1481 T_EXPECT_GE_ULLONG(preginfo_path
.prp_prinfo
.pri_offset
, (uint64_t)PAGE_SIZE
,
1482 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_offset");
1483 T_EXPECT_NE_UINT((preginfo_path
.prp_prinfo
.pri_protection
^ (VM_PROT_WRITE
| VM_PROT_EXECUTE
)), 0U,
1484 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_protection");
1485 #if defined(__arm__) || defined(__arm64__)
1486 T_EXPECT_GT_UINT(preginfo_path
.prp_prinfo
.pri_max_protection
, 0U,
1487 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_max_protection");
1489 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_max_protection
^ VM_PROT_ALL
), 0U,
1490 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_max_protection");
1492 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_inheritance
^ VM_INHERIT_COPY
), 0U,
1493 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_inheritance");
1494 T_EXPECT_EQ_UINT((preginfo_path
.prp_prinfo
.pri_behavior
^ VM_BEHAVIOR_DEFAULT
), 0U,
1495 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_behavior");
1496 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_user_wired_count
, 0U,
1497 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_user_wired_count");
1498 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_user_tag
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_user_tag");
1499 T_EXPECT_NE_UINT((preginfo_path
.prp_prinfo
.pri_flags
^ (PROC_REGION_SUBMAP
| PROC_REGION_SHARED
)), 0U,
1500 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_flags");
1501 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_resident
, 0U,
1502 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_pages_resident");
1503 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_shared_now_private
, 0U,
1504 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_pages_shared_now_private");
1505 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_swapped_out
, 0U,
1506 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_pages_swapped_out");
1507 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_pages_dirtied
, 0U,
1508 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_pages_dirtied");
1509 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_ref_count
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_ref_count");
1510 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_shadow_depth
, 0U,
1511 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_shadow_depth");
1512 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_share_mode
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_share_mode");
1513 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_private_pages_resident
, 0U,
1514 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_private_pages_resident");
1515 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_shared_pages_resident
, 0U,
1516 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_shared_pages_resident");
1517 T_EXPECT_NE_ULLONG(preginfo_path
.prp_prinfo
.pri_address
, 0ULL, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_addr");
1518 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_obj_id
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_obj_id");
1519 T_EXPECT_GE_ULLONG(preginfo_path
.prp_prinfo
.pri_size
, (uint64_t)PAGE_SIZE
,
1520 "PROC_PIDREGIONPATHINFO3 returns valid value for pri_size");
1521 T_EXPECT_EQ_UINT(preginfo_path
.prp_prinfo
.pri_depth
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for pri_depth");
1523 T_EXPECT_EQ_INT(preginfo_path
.prp_vip
.vip_vi
.vi_type
, VREG
, "PROC_PIDREGIONPATHINFO3 returns valid value for vi_type");
1524 T_EXPECT_EQ_INT(preginfo_path
.prp_vip
.vip_vi
.vi_pad
, 0, "PROC_PIDREGIONPATHINFO3 returns valid value for vi_pad");
1525 T_EXPECT_NE_INT(preginfo_path
.prp_vip
.vip_vi
.vi_fsid
.val
[0], 0,
1526 "PROC_PIDREGIONPATHINFO3 returns valid value for vi_fsid.val[0]");
1527 T_EXPECT_NE_INT(preginfo_path
.prp_vip
.vip_vi
.vi_fsid
.val
[1], 0,
1528 "PROC_PIDREGIONPATHINFO3 returns valid value for vi_fsid.val[1]");
1530 * Basic sanity checks for vnode stat returned by the API
1532 T_EXPECT_NE_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_dev
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_dev");
1533 T_EXPECT_EQ_UINT(((preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_mode
& S_IFMT
) ^ S_IFREG
), 0,
1534 "PROC_PIDREGIONPATHINFO3 returns valid value for vst_mode");
1535 T_EXPECT_EQ_USHORT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_nlink
, (unsigned short)1,
1536 "PROC_PIDREGIONPATHINFO3 returns valid value for vst_nlink");
1537 T_EXPECT_NE_ULLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_ino
, 0ULL,
1538 "PROC_PIDREGIONPATHINFO3 returns valid value for vst_ino");
1540 * No way to confirm actual ownership or binary. Just log the value
1542 T_EXPECT_GE_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_uid
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_uid");
1543 T_EXPECT_GE_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_gid
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_gid");
1544 T_EXPECT_GE_LLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_size
, (off_t
)CONF_BLK_SIZE
,
1545 "PROC_PIDREGIONPATHINFO3 returns valid value for vst_size");
1546 T_EXPECT_GE_LLONG(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_blocks
, 1LL,
1547 "PROC_PIDREGIONPATHINFO3 returns valid value for vst_blocks");
1548 T_EXPECT_GE_UINT(preginfo_path
.prp_vip
.vip_vi
.vi_stat
.vst_blksize
, CONF_BLK_SIZE
,
1549 "PROC_PIDREGIONPATHINFO3 returns valid value for vst_blksize");
1551 free_proc_info(proc_info
, 1);
1554 T_DECL(proc_info_proc_pidvnodepathinfo
,
1555 "Test to verify PROC_PIDVNODEPATHINFO returns valid information about the process",
1556 T_META_ASROOT(true),
1557 T_META_LTEPHASE(LTE_POSTINIT
))
1559 void * proc_info
[1];
1560 proc_info_caller(PVNINFO
, proc_info
, NULL
);
1561 struct proc_vnodepathinfo pvninfo
= *((struct proc_vnodepathinfo
*)proc_info
[0]);
1563 T_EXPECT_EQ_INT(pvninfo
.pvi_cdir
.vip_vi
.vi_type
, VDIR
, "PROC_PIDVNODEPATHINFO returns valid value for vi_type");
1564 T_EXPECT_EQ_INT(pvninfo
.pvi_cdir
.vip_vi
.vi_pad
, 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_pad");
1565 T_EXPECT_NE_INT(pvninfo
.pvi_cdir
.vip_vi
.vi_fsid
.val
[0], 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_fsid.val[0]");
1566 T_EXPECT_NE_INT(pvninfo
.pvi_cdir
.vip_vi
.vi_fsid
.val
[1], 0, "PROC_PIDVNODEPATHINFO returns valid value for vi_fsid.val[1]");
1568 * Basic sanity checks for vnode stat returned by the API
1570 T_EXPECT_NE_UINT(pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_dev
, 0U, "PROC_PIDVNODEPATHINFO returns valid value for vst_dev");
1571 T_EXPECT_EQ_INT(((pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_mode
& S_IFMT
) ^ S_IFDIR
), 0,
1572 "PROC_PIDVNODEPATHINFO returns valid value for vst_mode");
1573 T_EXPECT_GE_USHORT(pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_nlink
, (unsigned short)2,
1574 "PROC_PIDVNODEPATHINFO returns valid value for vst_nlink");
1575 T_EXPECT_NE_ULLONG(pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_ino
, 0ULL, "PROC_PIDVNODEPATHINFO returns valid value for vst_ino");
1576 T_EXPECT_GE_UINT(pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_uid
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_uid");
1577 T_EXPECT_GE_UINT(pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_gid
, 0U, "PROC_PIDREGIONPATHINFO3 returns valid value for vst_gid");
1578 T_EXPECT_GT_LLONG(pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_size
, 0LL, "PROC_PIDVNODEPATHINFO returns valid value for vst_size");
1579 T_EXPECT_GE_LLONG(pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_blocks
, 0LL, "PROC_PIDVNODEPATHINFO returns valid value for vst_blocks");
1580 T_EXPECT_GE_UINT(pvninfo
.pvi_cdir
.vip_vi
.vi_stat
.vst_blksize
, CONF_BLK_SIZE
,
1581 "PROC_PIDVNODEPATHINFO returns valid value for vst_blksize");
1583 free_proc_info(proc_info
, 1);
1586 * The remaining tests break from the pattern of the other PROC_INFO_CALL_PIDINFO tests.
1587 * We call proc_info directly as it's more efficient
1590 T_DECL(proc_info_pidinfo_proc_pidlistfds
,
1591 "proc_info API tests to verify PROC_INFO_CALL_PIDINFO/PROC_PIDLISTFDS",
1592 T_META_ASROOT(true),
1593 T_META_LTEPHASE(LTE_POSTINIT
))
1596 int orig_nfiles
= 0;
1597 struct proc_fdinfo
* fd_info
= NULL
;
1599 T_LOG("Test to verify PROC_PIDLISTFDS returns sane number of open files");
1600 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, getpid(), PROC_PIDLISTFDS
, (uint32_t)0, (user_addr_t
)0, (uint32_t)0);
1601 orig_nfiles
= retval
/ (int)sizeof(struct proc_fdinfo
);
1602 T_EXPECT_GE_INT(orig_nfiles
, CONF_OPN_FILE_COUNT
, "The number of open files is lower than expected.");
1605 * Allocate a buffer of expected size + 1 to ensure that
1606 * the API still returns expected size
1607 * i.e. 3 + 1 = 4 open fds
1609 T_LOG("Test to verify PROC_PIDLISTFDS returns valid fd information");
1610 fd_info
= malloc(sizeof(*fd_info
) * 5);
1611 tmp_fd
= open(CONF_TMP_FILE_PATH
, O_RDONLY
| O_CREAT
);
1612 T_LOG("tmp_fd val:%d", tmp_fd
);
1614 T_EXPECT_POSIX_SUCCESS(tmp_fd
, "open() for PROC_PIDLISTFDS");
1616 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, getpid(), PROC_PIDLISTFDS
, (uint32_t)0, (user_addr_t
)fd_info
,
1617 (uint32_t)(sizeof(*fd_info
) * 5));
1618 retval
= retval
/ (int)sizeof(struct proc_fdinfo
);
1622 for (int i
= 0; i
< retval
; i
++) {
1624 * Check only for the fd that we control.
1626 if (tmp_fd
!= fd_info
[i
].proc_fd
) {
1629 T_EXPECT_EQ_UINT(fd_info
[i
].proc_fdtype
, (unsigned int)PROX_FDTYPE_VNODE
, "Correct proc_fdtype for returned fd");
1632 T_EXPECT_GE_INT(retval
, 4, "Correct number of fds was returned.");
1639 T_DECL(proc_info_proc_pidpathinfo
,
1640 "Test to verify PROC_PIDPATHINFO returns valid information about the process",
1641 T_META_ASROOT(true),
1642 T_META_LTEPHASE(LTE_POSTINIT
))
1644 char * pid_path
= NULL
;
1645 pid_path
= malloc(sizeof(char) * PROC_PIDPATHINFO_MAXSIZE
);
1646 T_EXPECT_NOTNULL(pid_path
, "malloc for PROC_PIDPATHINFO");
1647 int retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, getpid(), PROC_PIDPATHINFO
, (uint64_t)0, (user_addr_t
)pid_path
,
1648 (uint32_t)PROC_PIDPATHINFO_MAXSIZE
);
1649 T_EXPECT_EQ_INT(retval
, 0, "__proc_info call for PROC_PIDPATHINFO");
1651 T_EXPECT_NE_PTR((void *)(strcasestr(pid_path
, CONF_CMD_NAME
)), NULL
, "PROC_PIDPATHINFOreturns valid value for pid_path");
1656 T_DECL(proc_info_proc_pidlistfileports
,
1657 "Test to verify PROC_PIDLISTFILEPORTS returns valid information about the process",
1658 T_META_ASROOT(true),
1659 T_META_LTEPHASE(LTE_POSTINIT
))
1661 struct proc_fileportinfo
* fileport_info
= NULL
;
1662 mach_port_t tmp_file_port
= MACH_PORT_NULL
;
1663 proc_config_t proc_config
= spawn_child_processes(1, proc_info_call_pidinfo_handler
);
1664 int child_pid
= proc_config
->child_pids
[0];
1667 * Create a file port
1669 tmp_fd
= open(CONF_TMP_FILE_PATH
, O_RDWR
| O_CREAT
);
1670 int retval
= fileport_makeport(tmp_fd
, &tmp_file_port
);
1671 T_EXPECT_POSIX_SUCCESS(retval
, "fileport_makeport() for PROC_PIDLISTFILEPORTS");
1674 * Like the other APIs, this returns the actual count + 20. Hence we expect it to be atleast 1 (that we created)
1676 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, getpid(), PROC_PIDLISTFILEPORTS
, (uint64_t)0, (user_addr_t
)0, (uint32_t)0);
1677 T_EXPECT_GE_INT(retval
/ (int)sizeof(fileport_info
), 1,
1678 "__proc_info call for PROC_PIDLISTFILEPORTS to get total ports in parent");
1681 * Child doesn't have any fileports, should return zero
1683 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDLISTFILEPORTS
, (uint64_t)0, (user_addr_t
)0, (uint32_t)0);
1684 T_EXPECT_EQ_INT(retval
/ (int)sizeof(fileport_info
), 0,
1685 "__proc_info call for PROC_PIDLISTFILEPORTS to get total ports in child");
1687 fileport_info
= malloc(sizeof(*fileport_info
) * (size_t)retval
);
1688 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, getpid(), PROC_PIDLISTFILEPORTS
, (uint64_t)0, (user_addr_t
)fileport_info
,
1689 (uint32_t)sizeof(*fileport_info
));
1690 T_EXPECT_EQ_INT(retval
, (int)sizeof(*fileport_info
), "__proc_info call for PROC_PIDLISTFILEPORTS");
1692 T_EXPECT_NE_UINT(fileport_info
->proc_fileport
, (uint32_t)0, "PROC_PIDLISTFILEPORTS returns valid value for proc_fileport");
1693 T_EXPECT_EQ_UINT(fileport_info
->proc_fdtype
, (uint32_t)PROX_FDTYPE_VNODE
,
1694 "PROC_PIDLISTFILEPORTS returns valid value for proc_fdtype");
1697 * Cleanup for the fileport
1699 mach_port_deallocate(mach_task_self(), tmp_file_port
);
1700 tmp_file_port
= MACH_PORT_NULL
;
1701 free(fileport_info
);
1702 fileport_info
= NULL
;
1705 free_proc_config(proc_config
);
1708 T_DECL(proc_info_proc_pidcoalitioninfo
,
1709 "Test to verify PROC_PIDCOALITIONINFO returns valid information about the process",
1710 T_META_ASROOT(true),
1711 T_META_LTEPHASE(LTE_POSTINIT
))
1713 proc_config_t proc_config
= spawn_child_processes(1, proc_info_call_pidinfo_handler
);
1714 int child_pid
= proc_config
->child_pids
[0];
1716 struct proc_pidcoalitioninfo pci_parent
;
1717 struct proc_pidcoalitioninfo pci_child
;
1718 int retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, getpid(), PROC_PIDCOALITIONINFO
, (uint64_t)0, (user_addr_t
)&pci_parent
,
1719 (uint32_t)sizeof(pci_parent
));
1720 T_EXPECT_EQ_INT(retval
, (int)sizeof(pci_parent
), "__proc_info call for PROC_PIDCOALITIONINFO (parent)");
1721 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDCOALITIONINFO
, (uint64_t)0, (user_addr_t
)&pci_child
,
1722 (uint32_t)sizeof(pci_child
));
1723 T_EXPECT_EQ_INT(retval
, (int)sizeof(pci_child
), "__proc_info call for PROC_PIDCOALITIONINFO (child)");
1726 * Coalition IDs should match for child and parent
1728 for (int i
= 0; i
< COALITION_NUM_TYPES
; i
++) {
1729 T_EXPECT_EQ_ULLONG(pci_parent
.coalition_id
[i
], pci_child
.coalition_id
[i
],
1730 "PROC_PIDCOALITIONINFO returns valid value for coalition_id");
1733 free_proc_config(proc_config
);
1736 T_DECL(proc_info_proc_pidworkqueueinfo
,
1737 "Test to verify PROC_PIDWORKQUEUEINFO returns valid information about the process",
1738 T_META_ASROOT(true),
1739 T_META_LTEPHASE(LTE_POSTINIT
))
1741 proc_config_t proc_config
= spawn_child_processes(1, proc_info_call_pidinfo_handler
);
1742 int child_pid
= proc_config
->child_pids
[0];
1743 send_action_to_child_processes(proc_config
, ACT_PHASE5
);
1745 struct proc_workqueueinfo pwqinfo
;
1747 int retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDWORKQUEUEINFO
, (uint64_t)0, (user_addr_t
)&pwqinfo
,
1748 (uint32_t)sizeof(pwqinfo
));
1749 T_EXPECT_EQ_INT(retval
, (int)sizeof(pwqinfo
), "__proc_info call for PROC_PIDWORKQUEUEINFO");
1752 size_t ncpu_size
= sizeof(ncpu
);
1753 retval
= sysctlbyname("hw.ncpu", (void *)&ncpu
, &ncpu_size
, NULL
, 0);
1754 T_EXPECT_EQ_INT(retval
, 0, "sysctl() for PROC_PIDWORKQUEUEINFO");
1755 T_EXPECT_GE_UINT(pwqinfo
.pwq_nthreads
, (uint32_t)1, "PROC_PIDWORKQUEUEINFO returns valid value for pwq_nthreads");
1756 T_EXPECT_GE_UINT(pwqinfo
.pwq_blockedthreads
+ pwqinfo
.pwq_runthreads
, (uint32_t)1,
1757 "PROC_PIDWORKQUEUEINFO returns valid value for pwqinfo.pwq_runthreads/pwq_blockedthreads");
1758 T_EXPECT_EQ_UINT(pwqinfo
.pwq_state
, (uint32_t)0, "PROC_PIDWORKQUEUEINFO returns valid value for pwq_state");
1760 kill_child_processes(proc_config
);
1761 free_proc_config(proc_config
);
1763 T_DECL(proc_info_proc_pidnoteexit
,
1764 "Test to verify PROC_PIDNOTEEXIT returns valid information about the process",
1765 T_META_ASROOT(true),
1766 T_META_LTEPHASE(LTE_POSTINIT
))
1769 * Ask the child to close pipe and quit, cleanup pipes for parent
1771 proc_config_t proc_config
= spawn_child_processes(1, proc_info_call_pidinfo_handler
);
1772 int child_pid
= proc_config
->child_pids
[0];
1773 send_action_to_child_processes(proc_config
, ACT_EXIT
);
1775 uint32_t exit_data
= 0;
1776 int retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDNOTEEXIT
, (uint64_t)(NOTE_EXITSTATUS
| NOTE_EXIT_DETAIL
),
1777 (user_addr_t
)&exit_data
, (uint32_t)sizeof(exit_data
));
1778 T_EXPECT_EQ_INT(retval
, (int)sizeof(exit_data
), "__proc_info call for PROC_PIDNOTEEXIT");
1780 T_EXPECT_EQ_UINT(exit_data
, 0U, "PROC_PIDNOTEEXIT returned valid value for exit_data");
1782 free_proc_config(proc_config
);
1785 T_DECL(proc_info_negative_tests
,
1786 "Test to validate PROC_INFO_CALL_PIDINFO for invalid arguments",
1787 T_META_ASROOT(true),
1788 T_META_LTEPHASE(LTE_POSTINIT
))
1790 proc_config_t proc_config
= spawn_child_processes(1, proc_info_call_pidinfo_handler
);
1791 int child_pid
= proc_config
->child_pids
[0];
1792 uint32_t exit_data
= 0;
1795 __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDNOTEEXIT
, (uint64_t)0, (user_addr_t
)&exit_data
, (uint32_t)0);
1796 T_EXPECT_EQ_INT(errno
, ENOMEM
, "PROC_INFO_CALL_PIDINFO call should fail with ENOMEM if buffersize is zero");
1797 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, PROC_PIDPATHINFO
, (uint64_t)0, (user_addr_t
)&exit_data
,
1798 (uint32_t)PROC_PIDPATHINFO_MAXSIZE
+ 1);
1799 T_EXPECT_EQ_INT(errno
, EOVERFLOW
,
1800 "PROC_INFO_CALL_PIDINFO call should fail with EOVERFLOW if buffersize is larger than PROC_PIDPATHINFO_MAXSIZE");
1801 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, -1, PROC_PIDNOTEEXIT
, (uint64_t)0, (user_addr_t
)&exit_data
,
1802 (uint32_t)sizeof(exit_data
));
1803 T_EXPECT_EQ_INT(errno
, ESRCH
, "PROC_INFO_CALL_PIDINFO call should fail with ESRCH for invalid process id");
1804 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, child_pid
, -1U, (uint64_t)0, (user_addr_t
)&exit_data
, (uint32_t)sizeof(exit_data
));
1805 T_EXPECT_EQ_INT(errno
, EINVAL
, "PROC_INFO_CALL_PIDINFO call should fail with EINVAL for invalid flavor");
1806 retval
= __proc_info(PROC_INFO_CALL_PIDINFO
, 0, PROC_PIDWORKQUEUEINFO
, (uint64_t)0, (user_addr_t
)0, (uint32_t)0);
1807 T_EXPECT_EQ_INT(errno
, EINVAL
,
1808 "PROC_INFO_CALL_PIDINFO call should fail with EINVAL if flavor is PROC_PIDWORKQUEUEINFO and pid=0");
1810 free_proc_config(proc_config
);
1814 * END PROC_INFO_CALL_PIDINFO DECLs
1817 #pragma mark proc_list_uptrs
1820 static uint64_t uptrs
[NUPTRS
] = {0x1122334455667788ULL
, 0x99aabbccddeeff00ULL
, 0xaabbaaddccaaffeeULL
, 0xcc000011ccaa7755ULL
};
1822 static const char * uptr_names
[NUPTRS
];
1825 print_uptrs(int argc
, char * const * argv
)
1827 for (int i
= 0; i
< argc
; i
++) {
1829 unsigned long pid
= strtoul(argv
[i
], &end
, 0);
1830 if (pid
> INT_MAX
) {
1831 printf("error: pid '%lu' would overflow an integer\n", pid
);
1833 if (end
== argv
[i
]) {
1834 printf("error: could not parse '%s' as a pid\n", argv
[i
]);
1837 int uptrs_count
= proc_list_uptrs((int)pid
, NULL
, 0);
1838 if (uptrs_count
== 0) {
1839 printf("no uptrs for process %d\n", (int)pid
);
1844 unsigned int uptrs_len
= (unsigned int)uptrs_count
+ 32;
1846 uint64_t * uptrs_alloc
= malloc(sizeof(uint64_t) * uptrs_len
);
1847 os_assert(uptrs_alloc
!= NULL
);
1849 uptrs_count
= proc_list_uptrs((int)pid
, uptrs_alloc
, (uint32_t)(sizeof(uint64_t) * uptrs_len
));
1850 printf("process %d has %d uptrs:\n", (int)pid
, uptrs_count
);
1851 if (uptrs_count
> (int)uptrs_len
) {
1852 uptrs_count
= (int)uptrs_len
;
1854 for (int j
= 0; j
< uptrs_count
; j
++) {
1855 printf("%#17" PRIx64
"\n", uptrs_alloc
[j
]);
1860 T_DECL(proc_list_uptrs
, "the kernel should return any up-pointers it knows about", T_META_ALL_VALID_ARCHS(YES
))
1863 print_uptrs(argc
, argv
);
1864 T_SKIP("command line invocation of tool, not test");
1867 unsigned int cur_uptr
= 0;
1871 T_ASSERT_POSIX_SUCCESS(kq
, "kqueue");
1874 * Should find uptrs on file-type knotes and generic knotes (two
1875 * different search locations, internally).
1877 struct kevent64_s events
[2];
1878 memset(events
, 0, sizeof(events
));
1880 uptr_names
[cur_uptr
] = "kqueue file-backed knote";
1881 events
[0].filter
= EVFILT_WRITE
;
1882 events
[0].ident
= STDOUT_FILENO
;
1883 events
[0].flags
= EV_ADD
;
1884 events
[0].udata
= uptrs
[cur_uptr
++];
1886 uptr_names
[cur_uptr
] = "kqueue non-file-backed knote";
1887 events
[1].filter
= EVFILT_USER
;
1888 events
[1].ident
= 1;
1889 events
[1].flags
= EV_ADD
;
1890 events
[1].udata
= uptrs
[cur_uptr
++];
1892 int kev_err
= kevent64(kq
, events
, sizeof(events
) / sizeof(events
[0]), NULL
, 0, KEVENT_FLAG_IMMEDIATE
, NULL
);
1893 T_ASSERT_POSIX_SUCCESS(kev_err
, "register events with kevent64");
1896 * Should find uptrs both on a kevent_id kqueue and in a workloop
1897 * kqueue's knote's udata field.
1899 uptr_names
[cur_uptr
] = "dynamic kqueue non-file-backed knote";
1900 struct kevent_qos_s events_id
[] = {{.filter
= EVFILT_USER
, .ident
= 1, .flags
= EV_ADD
, .udata
= uptrs
[cur_uptr
++]}};
1902 uptr_names
[cur_uptr
] = "dynamic kqueue ID";
1903 kev_err
= kevent_id(uptrs
[cur_uptr
++], events_id
, 1, NULL
, 0, NULL
, NULL
, KEVENT_FLAG_WORKLOOP
| KEVENT_FLAG_IMMEDIATE
);
1904 T_ASSERT_POSIX_SUCCESS(kev_err
, "register event with kevent_id");
1907 int uptrs_count
= proc_list_uptrs(getpid(), NULL
, 0);
1909 T_ASSERT_POSIX_SUCCESS(uptrs_count
, "proc_list_uptrs");
1911 T_EXPECT_EQ(uptrs_count
, NUPTRS
, "should see correct number of up-pointers");
1913 uint64_t uptrs_obs
[NUPTRS
] = {0};
1914 uptrs_count
= proc_list_uptrs(getpid(), uptrs_obs
, sizeof(uptrs_obs
));
1916 T_ASSERT_POSIX_SUCCESS(uptrs_count
, "proc_list_uptrs");
1918 for (int i
= 0; i
< uptrs_count
; i
++) {
1920 for (int j
= 0; j
< NUPTRS
; j
++) {
1921 if (uptrs_obs
[i
] == uptrs
[j
]) {
1926 T_FAIL("unexpected up-pointer found: %#" PRIx64
, uptrs_obs
[i
]);
1929 T_PASS("found up-pointer for %s", uptr_names
[found
]);
1933 uint64_t up_overflow
[2] = {0};
1934 uptrs_count
= proc_list_uptrs(getpid(), up_overflow
, sizeof(uint64_t)+1);
1935 T_ASSERT_EQ(up_overflow
[1], 0 , "overflow check");
1938 #pragma mark dynamic kqueue info
1940 #define EXPECTED_ID UINT64_C(0x1122334455667788)
1941 #define EXPECTED_UDATA UINT64_C(0x99aabbccddeeff00)
1943 #define KQ_WORKLOOP 0x80
1947 setup_kevent_id(kqueue_id_t id
)
1949 struct kevent_qos_s events_id
[] = {{.filter
= EVFILT_USER
, .ident
= 1, .flags
= EV_ADD
, .udata
= EXPECTED_UDATA
}};
1951 int err
= kevent_id(id
, events_id
, 1, NULL
, 0, NULL
, NULL
, KEVENT_FLAG_WORKLOOP
| KEVENT_FLAG_IMMEDIATE
);
1952 T_ASSERT_POSIX_SUCCESS(err
, "register event with kevent_id");
1955 static kqueue_id_t
*
1956 list_kqids(pid_t pid
, int * nkqids_out
)
1958 int kqids_len
= 256;
1960 kqueue_id_t
* kqids
= NULL
;
1961 uint32_t kqids_size
;
1964 if (os_mul_overflow(sizeof(kqueue_id_t
), kqids_len
, &kqids_size
)) {
1966 T_ASSERT_GT(kqids_len
, PROC_PIDDYNKQUEUES_MAX
, NULL
);
1967 kqids_len
= PROC_PIDDYNKQUEUES_MAX
;
1971 kqids
= malloc(kqids_size
);
1973 T_ASSERT_NOTNULL(kqids
, "malloc(%" PRIu32
")", kqids_size
);
1976 nkqids
= proc_list_dynkqueueids(pid
, kqids
, kqids_size
);
1977 if (nkqids
> kqids_len
&& kqids_len
< PROC_PIDDYNKQUEUES_MAX
) {
1979 if (kqids_len
> PROC_PIDDYNKQUEUES_MAX
) {
1980 kqids_len
= PROC_PIDDYNKQUEUES_MAX
;
1987 *nkqids_out
= nkqids
;
1991 T_DECL(list_dynamic_kqueues
, "the kernel should list IDs of dynamic kqueues", T_META_ALL_VALID_ARCHS(true))
1996 setup_kevent_id(EXPECTED_ID
);
1997 kqueue_id_t
* kqids
= list_kqids(getpid(), &nkqids
);
1998 T_ASSERT_GE(nkqids
, 1, "at least one dynamic kqueue is listed");
1999 for (int i
= 0; i
< nkqids
; i
++) {
2000 if (kqids
[i
] == EXPECTED_ID
) {
2002 T_PASS("found expected dynamic kqueue ID");
2004 T_LOG("found another dynamic kqueue with ID %#" PRIx64
, kqids
[i
]);
2009 T_FAIL("could not find dynamic ID of kqueue created");
2015 T_DECL(dynamic_kqueue_basic_info
, "the kernel should report valid basic dynamic kqueue info", T_META_ALL_VALID_ARCHS(true))
2017 struct kqueue_info kqinfo
;
2020 setup_kevent_id(EXPECTED_ID
);
2021 ret
= proc_piddynkqueueinfo(getpid(), PROC_PIDDYNKQUEUE_INFO
, EXPECTED_ID
, &kqinfo
, sizeof(kqinfo
));
2022 T_ASSERT_POSIX_SUCCESS(ret
, "proc_piddynkqueueinfo(... PROC_PIDDYNKQUEUE_INFO ...)");
2024 T_ASSERT_GE(ret
, (int)sizeof(kqinfo
), "PROC_PIDDYNKQUEUE_INFO should return the right size");
2026 T_EXPECT_NE(kqinfo
.kq_state
& KQ_WORKLOOP
, 0U, "kqueue info should be for a workloop kqueue");
2027 T_EXPECT_EQ(kqinfo
.kq_stat
.vst_ino
, EXPECTED_ID
, "inode field should be the kqueue's ID");
2030 T_DECL(dynamic_kqueue_extended_info
, "the kernel should report valid extended dynamic kqueue info", T_META_ALL_VALID_ARCHS(true))
2032 struct kevent_extinfo kqextinfo
[1];
2035 setup_kevent_id(EXPECTED_ID
);
2036 ret
= proc_piddynkqueueinfo(getpid(), PROC_PIDDYNKQUEUE_EXTINFO
, EXPECTED_ID
, kqextinfo
, sizeof(kqextinfo
));
2037 T_ASSERT_POSIX_SUCCESS(ret
, "proc_piddynkqueueinfo(... PROC_PIDDYNKQUEUE_EXTINFO ...)");
2039 T_ASSERT_EQ(ret
, 1, "PROC_PIDDYNKQUEUE_EXTINFO should return a single knote");
2041 T_EXPECT_EQ(kqextinfo
[0].kqext_kev
.ident
, 1ULL, "kevent identifier matches what was configured");
2042 T_EXPECT_EQ(kqextinfo
[0].kqext_kev
.filter
, (short)EVFILT_USER
, "kevent filter matches what was configured");
2043 T_EXPECT_EQ(kqextinfo
[0].kqext_kev
.udata
, EXPECTED_UDATA
, "kevent udata matches what was configured");
2046 #pragma mark proc_listpids
2048 T_DECL(list_kdebug_pids
, "the kernel should report processes that are filtered by kdebug", T_META_ASROOT(YES
))
2050 int mib
[4] = {CTL_KERN
, KERN_KDEBUG
};
2055 size_t regsize
= sizeof(reg
);
2057 mib
[2] = KERN_KDREMOVE
;
2058 ret
= sysctl(mib
, 3, NULL
, NULL
, NULL
, 0);
2060 T_ASSERT_POSIX_SUCCESS(ret
, "KERN_KDREMOVE sysctl");
2062 mib
[2] = KERN_KDSETBUF
;
2064 ret
= sysctl(mib
, 4, NULL
, NULL
, NULL
, 0);
2066 T_ASSERT_POSIX_SUCCESS(ret
, "KERN_KDSETBUF sysctl");
2068 mib
[2] = KERN_KDSETUP
;
2069 ret
= sysctl(mib
, 3, NULL
, NULL
, NULL
, 0);
2071 T_ASSERT_POSIX_SUCCESS(ret
, "KERN_KDSETUP sysctl");
2073 npids
= proc_listpids(PROC_KDBG_ONLY
, 0, pids
, sizeof(pids
));
2074 T_EXPECT_EQ(npids
, 0, "no processes should be filtered initially");
2076 reg
.type
= KDBG_TYPENONE
;
2077 reg
.value1
= (unsigned int)getpid();
2078 reg
.value2
= 1; /* set the pid in the filter */
2079 mib
[2] = KERN_KDPIDTR
;
2080 ret
= sysctl(mib
, 3, ®
, ®size
, NULL
, 0);
2081 T_ASSERT_POSIX_SUCCESS(ret
, "KERN_KDPIDTR sysctl to set a pid in the filter");
2083 npids
= proc_listpids(PROC_KDBG_ONLY
, 0, pids
, sizeof(pids
));
2085 T_EXPECT_EQ(npids
, 1, "a process should be filtered");
2086 T_EXPECT_EQ(pids
[0], getpid(), "process filtered should be the one that was set");
2088 mib
[2] = KERN_KDREMOVE
;
2089 ret
= sysctl(mib
, 3, NULL
, NULL
, NULL
, 0);
2091 T_ASSERT_POSIX_SUCCESS(ret
, "KERN_KDREMOVE sysctl");