본문 바로가기

Core BSP 분석/리눅스 커널 핵심 분석

cmm: thread dump

;****************************************************************************
;**         thread_process_dump_austin.cmm
;**
;**         This cmm file is designed to dump tcb information of all processes in Moorefield platform.
;**
;**
;****************************************************************************
;**
;**                        EDIT HISTORY FOR MODULE
;**
;**
;** when           who                 what, where, why
;** --------       ---             ------------------------------------------------------
;** 10/09/2014   austin.kim@lge.com    CREATE

Area.Create IO 80. 100.
Area.Select IO
Area IO

;=====specify the output directory of dump file, start =====
DIALOG.DIR D:\kernel_panic\*
ENTRY &ramdump_dir

;specify the output directory of dump file
&dump_debug_file="&ramdump_dir"+"/thread_all_dump.txt"
;=====specify the output directory of dump file, end =====

; display current configuration
DIALOG.MESSAGE "austin says: dump file will be saved under:== &ramdump_dir Wanna continue???"

printer.FILE &dump_debug_file
printer.OPEN &dump_debug_file

print
print
print "debugging"

&offset_next_task=0x268
&offset_next_thread=0x380
&offset_child_task=0x300
&next_child_task=0
&prev_child_task=0
&next_tcb_address=0
&tcb_stack_addr=0
&tcb_thread_info=0
&tcb_starting_address=0
&task_tcb_scan_times=0
&tcb_prev_list_address=0
&current_fp_addr=0
&dump_current_fp_addr=0
&thread_start_tcb_addr=0
&thread_group_next=0
&thread_group_prev=0
&thread_group_start=0
&thread_loop_condition=0
;wp.task.dtask

; have the first next process pointer contained in the init_task.tasks.next(list data structure)
&tcb_next_list_address=VAR.VALUE(init_task.tasks.next)
&tcb_starting_address=VAR.VALUE(init_task.tasks.next)
print "tcb_next_list_address: " &tcb_next_list_address

  WHILE &task_tcb_scan_times!=0xF0
  (
   ; obtain the starting address of the next process by using offset address.
   &next_tcb_address=&tcb_next_list_address-&offset_next_task
   ;&next_tcb_address=0xFFFF880052409030
   
   ;wp.v.v %string.on ((struct task_struct *)&next_tcb_address).comm ((struct task_struct *)&next_tcb_address).pid
   wp.v.v %string.on ((struct task_struct *)&next_tcb_address).pid
   ;v.v %string.on ((struct task_struct *)&next_tcb_address).pid
   ;wp.v.v  ((struct task_struct *)&next_tcb_address) 
;   &tcb_stack_addr=v.value( ((struct task_struct *)&next_tcb_address).stack )

; =================================
; configure a RBP address using thread_info, start
;=================================  
   &current_fp_addr=VAR.VALUE( ((struct task_struct *)&next_tcb_address).thread.sp)
   &dump_current_fp_addr=V.VALUE(*((uint64 *)(&current_fp_addr)))
 
;   print "fp_address   "  &current_fp_addr
;   print "fp_addressDump   "  &dump_current_fp_addr
  ;configure frame pointer register
  REGISTER.SET RBP &dump_current_fp_addr
 
  ;RIP register
  REGISTER.SET RIP data.quad(d:&dump_current_fp_addr+0x8)
 
  ; show call stack 
  wp.v.f
; =================================
; configure a RBP address using thread_info, end
;=================================  


   &thread_group_next=VAR.VALUE( ((struct task_struct *)&next_tcb_address).thread_group.next)
   &thread_group_prev=VAR.VALUE( ((struct task_struct *)&next_tcb_address).thread_group.prev)
  
   &thread_group_start=&thread_group_next
   ; if next pointer of thread_group is not equal to prev point of thread_group, this means there is another thread.
   if (&thread_group_next!=&thread_group_prev)
   (
        &thread_loop_condition=&task_tcb_scan_times
        ; continue loop until the next address is the same as the starting address
        WHILE &thread_loop_condition!=0x7
        (
;       &thread_group_next=&thread_group_next-&offset_next_thread
       &thread_start_tcb_addr=&thread_group_next-&offset_next_thread
      
       ;v.v %string.on ((struct task_struct *)&thread_start_tcb_addr).pid
      
       wp.v.v %string.on ((struct task_struct *)&thread_start_tcb_addr).comm ((struct task_struct *)&thread_start_tcb_addr).pid
    ;wp.v.v %string.on ((struct task_struct *)&thread_start_tcb_addr).pid
   
            ; =================================
            ; configure a RBP address using thread_info, start
            ;=================================  
            ;   &tcb_thread_info=VAR.VALUE( ((struct task_struct *)&thread_start_tcb_addr).thread)
               &current_fp_addr=VAR.VALUE( ((struct task_struct *)&thread_start_tcb_addr).thread.sp)
            ;   &current_fp_addr=VAR.VALUE( ((struct thread_struct *)&tcb_thread_info).sp)
               &dump_current_fp_addr=V.VALUE(*((uint64 *)(&current_fp_addr)))
             
            ;   print "fp_address   "  &current_fp_addr
            ;   print "fp_addressDump   "  &dump_current_fp_addr
              ;configure frame pointer register
              REGISTER.SET RBP &dump_current_fp_addr
            
              ;RIP register
              REGISTER.SET RIP data.quad(d:&dump_current_fp_addr+0x8)
             
              ; show call stack 
              wp.v.f
            ; =================================
            ; configure a RBP address using thread_info, end
            ;=================================     
   
    ;==================================================
    ; modify the next thread pointer, start
    ;==================================================
    &thread_group_next=VAR.VALUE( ((struct task_struct *)&thread_start_tcb_addr).thread_group.next)
   
    if (&thread_group_start==&thread_group_next)
    (
          &thread_loop_condition=0x7
    )
    ;==================================================
    ; modify the next thread pointer, end
    ;==================================================   
        ); end of WHILE &thread_loop_condition != 0x7
   
   )  
  
 ;  v.v %all (struct thread_struct)&tcb_thread_info
;   wp.v.v ((struct task_struct *)&next_tcb_address).pid
;   wp.v.v %all (struct task_struct *)(&next_tcb_address)

   &tcb_next_list_address=v.value( ((struct task_struct *)&next_tcb_address).tasks.next)
   &tcb_prev_list_address=v.value( ((struct task_struct *)&next_tcb_address).tasks.prev)
  
   ; for debugging
;   wp.v.v %hex ((struct task_struct *)&next_tcb_address).tasks.next
;   wp.v.v %hex ((struct task_struct *)&next_tcb_address).tasks.prev  

   &next_child_task=v.value( ((struct task_struct *)&next_tcb_address).children.next)
   &prev_child_task=v.value( ((struct task_struct *)&next_tcb_address).children.prev)
  
   if (&next_child_task!=&prev_child_task)
   (
       ;wp.v.v %string.on linux_banner
   )
  
   ; if next list address is equal to the start tcb address, exit while statement.
   if (&tcb_starting_address==&tcb_next_list_address)
   (
       &task_tcb_scan_times=0xF0  
   )
  
    ;&task_tcb_scan_times=&task_tcb_scan_times+1
  ); end of WHILE &task_tcb_scan_times != 0xF0

  ;&not_used_stack=&current_stack_address-&stack_limit_address
;print "not_used_stack address: " &not_used_stack

printer.CLOSE

ENDDO

'Core BSP 분석 > 리눅스 커널 핵심 분석' 카테고리의 다른 글

gdt_page  (0) 2023.05.06
process state  (0) 2023.05.06
x86 stack dump(1)  (0) 2023.05.05
register dump  (0) 2023.05.05
crashlogd  (0) 2023.05.05