Prints the process table, yay.
[virt-mem.git] / ps / virt_ps.ml
index 7d8534c..100a298 100644 (file)
@@ -24,8 +24,10 @@ open Virt_mem_utils
 open Virt_mem_types
 
 
-let run debug ({ domname = domname; mem = mem }, ksymmap, utsname) =
+let run debug (image, ksymmap, utsname) =
   try
+    let { domname = domname } = image in
+
     let kernel_version =
       match utsname with
       | None ->
@@ -41,25 +43,49 @@ supported Linux distribution, see this page about adding support:
       raise Exit
     );
 
-    let init_task =
-      let addr =
+    let task_struct_size = Kernel_task_struct.size kernel_version in
+
+    let init_task, init_task_addr =
+      let init_task_addr =
        try Ksymmap.find "init_task" ksymmap
        with Not_found ->
          eprintf (f_"%s: could not find init_task in kernel image\n") domname;
          raise Exit in
       let addr =
-       (Virt_mem_mmap.unsafe_typed_addr_of_addr addr :
+       (Virt_mem_mmap.unsafe_typed_addr_of_addr init_task_addr :
           [ `task_struct ] Virt_mem_mmap.typed_addr) in
-      Kernel_task_struct.get kernel_version mem addr in
+      let init_task = Kernel_task_struct.get kernel_version image.mem addr in
+      init_task, init_task_addr in
+
+    (* Starting at init_task, navigate through the linked list of
+     * tasks (through tasks.next).  Grab each task_struct as we go.
+     *)
+    let tasks, image =
+      let rec loop image acc task =
+       let next = task.Kernel_task_struct.tasks'next in
+       let next_addr = Virt_mem_mmap.unsafe_addr_of_typed_addr next in
+       if next_addr <> init_task_addr then (
+         let mapped =
+           Virt_mem_mmap.is_mapped_range image.mem
+             next_addr task_struct_size in
+         let image =
+           if not mapped then load_memory image next_addr task_struct_size
+           else image in
+         let task = Kernel_task_struct.get kernel_version image.mem next in
+         let acc = task :: acc in
+         loop image acc task
+       ) else
+         acc, image
+      in
+      loop image [] init_task in
 
-    printf "comm = %S prio = %Ld state = %Ld static_prio = %Ld tasks'next = %Lx\n"
-      init_task.Kernel_task_struct.comm
-      init_task.Kernel_task_struct.prio
-      init_task.Kernel_task_struct.state
-      init_task.Kernel_task_struct.static_prio
-      (Virt_mem_mmap.unsafe_addr_of_typed_addr init_task.Kernel_task_struct.tasks'next);
+    List.iter (
+      fun task ->
+       printf "%S\n" task.Kernel_task_struct.comm
+    ) tasks
 
-  with Exit -> ()
+  with
+  | Exit -> ()
 
 let summary = s_"list processes in virtual machine"
 let description = s_"\