open Kernel_task_struct
+let max_tasks = 10000
+
let find_tasks debug image ksymmap kernel_version =
if not (task_struct_known kernel_version) then (
eprintf (f_"%s: %s: unknown kernel version
get_task_struct kernel_version image.mem init_task_addr in
(* Starting at init_task, navigate through the linked list of
- * tasks (through tasks.next). Just make sure they are mapped
- * into memory.
+ * tasks (through tasks.next). Map them into memory and load
+ * them into a list.
*)
- let image =
- let rec loop image task =
- let next = task.task_struct_tasks'next in
- if next <> init_task_addr then (
- let mapped =
- Virt_mem_mmap.is_mapped_range image.mem next task_struct_size in
- let image =
- if not mapped then
- Virt_mem_types.load_memory image next task_struct_size
- else
- image in
- let task = get_task_struct kernel_version image.mem next in
- loop image task
+ let image, tasks =
+ let rec loop i image acc task =
+ if i <= max_tasks then (
+ let next = task.task_struct_tasks'next in
+ if next <> init_task_addr then (
+ let mapped =
+ Virt_mem_mmap.is_mapped_range image.mem next task_struct_size in
+ let image =
+ if not mapped then
+ Virt_mem_types.load_memory image next task_struct_size
+ else
+ image in
+ let task = get_task_struct kernel_version image.mem next in
+ loop (i+1) image (task :: acc) task
+ ) else
+ image, acc
) else
- image
+ failwith (sprintf (f_"%s: too many tasks") image.domname)
in
- loop image init_task in
+ loop 0 image [] init_task in
+
+ (* Convert to the internal format. *)
+ let tasks = List.rev_map (
+ fun task ->
+ { task_state = task.task_struct_state;
+ task_prio = task.task_struct_prio;
+ task_normal_prio = task.task_struct_normal_prio;
+ task_static_prio = task.task_struct_static_prio;
+ task_comm = truncate_c_string task.task_struct_comm;
+ task_pid = task.task_struct_pid }
+ ) tasks in
- image, Some init_task_addr
+ image, Some tasks
)