lkcd
[Top] [All Lists]

description: walk

To: lkcd@xxxxxxxxxxx
Subject: description: walk
From: "Andreas Herrmann" <AHERRMAN@xxxxxxxxxx>
Date: Thu, 16 Aug 2001 18:49:34 +0200
Importance: Normal
Sender: owner-lkcd@xxxxxxxxxxx
Here is some description about walk command regarding list_head support and
use of
iteration_threshold. (my comments are surrounded by /* */)

>> ? walk
COMMAND: walk
        -l
        struct field|offset addr [-f] [-n] [-h n|p]
        struct field|offset addr -s [-h n|p]
        struct field|offset addr -h n|p -t
        address offset size
        [-i iteration_threshold]
        [-w outfile]

    Walk a linked list of kernel structures or memory blocks.

    OPTIONS:
     -l
           Show a list of special structures that can be displayed in a
           predefined formatted manner.
           Currently there is support for a handful special structures.
     struct field|offset addr [-f] [-n] [-h n|p]
           Display  each entry of a linked list of special structures in
           a predefined formatted way.
           By default the output consists of one line for each structure.
           Using "-f" and/or "-n" a more detailed output is given.
           "-f" can be used for all special structures. "-n" works for
           special structures mm_struct and task_struct.
     struct field|offset addr -s [-h n|p]
           Each structure of a linked list is displayed in its entirety -
           in a C-like format. All structures for which type information is
           available can be displayed in this manner.
     -h n|p
           A linked list is constructed by following 'list_head' structures
           instead of next pointers. The argument specifies wether to
follow
           the next pointers of struct list_head (using 'n') or to follow
           the prev pointers of struct list_head (by using 'p').
           'field' or 'offset' is regarded as a member of type 'list_head'
           instead of a next pointer within the 'struct'. 'addr' is
           interpreted as a pointer to an anchor of a linked list of
           'struct list_head' structures.
     struct field|offset addr -h n|p -t
           Display each entry of a linked 'list_head'-list in one line.
           For each entry the address to the 'struct' structure, the
           address to the 'list_head' member within 'struct', and previous
           and next pointer of the embedded 'list_head' are given.
     address offset size
           Do a hex memory dump of each structure in a list.
           A start address ('address') of a structure, a byte offset
           ('offset') for the next pointer in the structure, and a
           structure size ('size') are required. 'size' bytes will be
           dumped for each entry in the constructed list.
     -i iteration_threshold
           By default certain loops are interrupted after 10'000 iterations
           to avoid endless loops while following invalid pointers. Using
           this option you can change the threshold for the current
command.
           A value '0' means infinite iteration threshold, i.e. no
           interruption of the loop is caused by reaching the threshold.

    While using "struct field|offset addr" without "-h" a structure name
    ('struct'), a field name ('field') or byte offset ('offset') for the
next
    pointer within the structure, and a pointer ('addr') to the first entry
    of the linked list must be given.

    Note: Using "-h" the anchor is not displayed as a structure 'struct'.

/* Example 1: walking through list_head lists
   Lets see of what use are list_head structures. */

>> task
              ADDR    UID    PID   PPID  STATE     FLAGS  NAME
===============================================================================
          0x1ac000      0      0      0      0         0  swapper
          0x9dc000      0      1      0      1     0x100  init
          0x9bc000      0      2      1      1      0x40  kmcheck
          0x9b4000      0      3      1      1      0x40  keventd
          0x960000      0      4      1      1     0x840  kswapd
          0x95c000      0      5      1      1     0x840  kreclaimd
          0x958000      0      6      1      1      0x40  bdflush
          0x954000      0      7      1      2      0x40  kupdated
         0x7844000      0     63      1      1      0x40  mdrecoveryd
         0x73cc000      0    303      1      2      0x40  syslogd
         0x7c24000      0    308      1      1     0x140  klogd
         0x697c000     32    318      1      1     0x140  portmap
         0x6910000     29    331      1      1     0x140  rpc.statd
         0x66cc000      0    378      1      1     0x140  sshd
         0x6644000      0    394      1      1     0x140  xinetd
         0x61a0000      0    413      1      1     0x140  sendmail
         0x7da4000      0    424      1      1      0x40  crond
         0x5d48000     43    522      1      1     0x140  xfs
         0x7db8000      0    542      1      1     0x100  login
         0x5904000      0    615    542      1     0x100  bash
         0x5688000      0    680      3      1      0x40  keventd
         0x55f4000      0    848    615      0         0  cat
         0x568c000      0    849    394      0     0x100  in.telnetd
         0x5594000      0    850    849      0         0  login
===============================================================================
24 active task structs found

>> offset task_struct.run_list
Offset: 104 bytes.

/* task_struct.run_list is of type (list_head*) */

>> print 0x5594000+104 -x
0x5594068

/* Now we've got a pointer to a list_head, we use it as the anchor */

>> walk task_struct run_list 0x5594068 -h n -t
        STRUCT ADDR               PREV           LISTHEAD
NEXT
============================================================================
                  0          0x568c068          0x5594068
0x55f4068
          0x55f4000          0x5594068          0x55f4068
0x1b25b0
           0x1b2548          0x55f4068           0x1b25b0
0x568c068
          0x568c000           0x1b25b0          0x568c068
0x5594068
============================================================================

>> walk task_struct run_list 0x5594068 -h n
              ADDR    UID    PID   PPID  STATE     FLAGS  NAME
===============================================================================
         0x55f4000      0    848    615      0         0  cat
          0x1b2548  1780328      0      0      0         0
         0x568c000      0    849    394      0     0x100  in.telnetd
===============================================================================

/* We have chosen a wrong anchor, the 2nd element seems not to be a
  task_struct. You can see this by looking up 0x1b2548 in the task table
above.
  So we choose this 2nd element as the new anchor.
  Take care, it corresponds to the 3rd element in the table before the
  last one. Up there we get from line 3, column 3 the desired address of
  the anchor: 0x1b25b0. */

>> walk task_struct run_list 0x1b25b0 -h n -t
        STRUCT ADDR               PREV           LISTHEAD
NEXT
============================================================================
                  0          0x55f4068           0x1b25b0
0x568c068
          0x568c000           0x1b25b0          0x568c068
0x5594068
          0x5594000          0x568c068          0x5594068
0x55f4068
          0x55f4000          0x5594068          0x55f4068
0x1b25b0
============================================================================

>> walk task_struct run_list 0x1b25b0 -h n
              ADDR    UID    PID   PPID  STATE     FLAGS  NAME
===============================================================================
         0x568c000      0    849    394      0     0x100  in.telnetd
         0x5594000      0    850    849      0         0  login
         0x55f4000      0    848    615      0         0  cat
===============================================================================

/* Cool. What we've got is the list of running tasks.
   What a waste of time. We could have seen this by looking up
   "STATE 0" processes in the task table above.
   But, let's look for more information about the anchor: */

>> fsym 0x1b25b0
      ADDR          OFFSET  TYPE         NAME
============================================================
          0x1b25b0       0  LOCAL_DATA   runqueue_head
============================================================
1 symbol found

/* Ok, makes sens to me. */

/* Using '-h p' changes the direction of our walk: */

>> walk task_struct run_list 0x1b25b0 -h p
              ADDR    UID    PID   PPID  STATE     FLAGS  NAME
===============================================================================
         0x55f4000      0    848    615      0         0  cat
         0x5594000      0    850    849      0         0  login
         0x568c000      0    849    394      0     0x100  in.telnetd
===============================================================================

>> walk task_struct run_list 0x1b25b0 -h p  -t
        STRUCT ADDR               NEXT           LISTHEAD
PREV
============================================================================
                  0          0x568c068           0x1b25b0
0x55f4068
          0x55f4000           0x1b25b0          0x55f4068
0x5594068
          0x5594000          0x55f4068          0x5594068
0x568c068
          0x568c000          0x5594068          0x568c068
0x1b25b0
============================================================================



/* Example 2: iteration threshold */

>> fsym inode_in_use inode_unused /* Further anchors of some list_head
lists. */
      ADDR  OFFSET  TYPE         NAME
============================================================
0xc0243e40       0  GLOBAL_DATA  inode_in_use
0xc0243e48       0  LOCAL_DATA   inode_unused
============================================================
2 symbols found

>> walk inode i_list 0xc0243e40 -h n
Neither a "predefined"structure, nor options '-s' or '-t' specified. Can't
print structure.

/* Bad luck.
   We will use '-t' and not '-s' for this demonstration.
   (Just take a look at 'whatis inode', and you know why.) */

>> walk inode i_list 0xc0243e40 -h n -t
STRUCT ADDR       PREV   LISTHEAD       NEXT
============================================
          0 0xcff38008 0xc0243e40 0xc5501c38

WARNING: Pointer broken. 0xc579c3e0, SHOULD BE: 0xc0243e40
 0xc5501c30 0xc579c3e0 0xc5501c38 0xc6314f68
 0xc6314f60 0xc5501c38 0xc6314f68 0xc2c44e20
 0xc2c44e18 0xc6314f68 0xc2c44e20 0xc8671340
 0xc8671338 0xc2c44e20 0xc8671340 0xc54da528
 0xc54da520 0xc8671340 0xc54da528 0xcbde6528
 0xcbde6520 0xc54da528 0xcbde6528 0xcf8771f8

...

 0xcaa8f710 0xca663340 0xcaa8f718 0xcb472b90
 0xcb472b88 0xcaa8f718 0xcb472b90 0xcb3e8b90
 0xcb3e8b88 0xcb472b90 0xcb3e8b90 0xcb3e9af0
 0xcb3e9ae8 0xcb3e8b90 0xcb3e9af0 0xcc279860
 0xcc279858 0xcb3e9af0 0xcc279860 0xcc2f9488
 0xcc2f9480 0xcc279860 0xcc2f9488 0xcd00c900
 0xcd00c8f8 0xcc2f9488 0xcd00c900 0xcceeb488

WARNING: Iteration threshold reached. Current threshold: 10000.
         Use "-i" to change threshold.

/* Ooops, something broken ... My dump was generated using 'livedump'
   in lcrash. So probably some inodes have changed.
   Furthermore the default iteration threshold was reached.
   We try again without any threshold value: */

>> walk inode i_list 0xc0243e40 -h n -t -i 0
STRUCT ADDR       PREV   LISTHEAD       NEXT
============================================
          0 0xcff38008 0xc0243e40 0xc5501c38

WARNING: Pointer broken. 0xc579c3e0, SHOULD BE: 0xc0243e40
 0xc5501c30 0xc579c3e0 0xc5501c38 0xc6314f68
 0xc6314f60 0xc5501c38 0xc6314f68 0xc2c44e20
 0xc2c44e18 0xc6314f68 0xc2c44e20 0xc8671340
 0xc8671338 0xc2c44e20 0xc8671340 0xc54da528
 0xc54da520 0xc8671340 0xc54da528 0xcbde6528
 0xcbde6520 0xc54da528 0xcbde6528 0xcf8771f8

...

 0xcfbfe7b0 0xcf985488 0xcfbfe7b8 0xcf8df9a8
 0xcf8df9a0 0xcfbfe7b8 0xcf8df9a8 0xcf9383e0
 0xcf9383d8 0xcf8df9a8 0xcf9383e0 0xcfbfe298
 0xcfbfe290 0xcf9383e0 0xcfbfe298 0xcfbfe3e0
 0xcfbfe3d8 0xcfbfe298 0xcfbfe3e0 0xcfbfe528
 0xcfbfe520 0xcfbfe3e0 0xcfbfe528 0xcfbff340
 0xcfbff338 0xcfbfe528 0xcfbff340 0xcff38e20
 0xcff38e18 0xcfbff340 0xcff38e20 0xcff395d0
 0xcff395c8 0xcff38e20 0xcff395d0 0xcff39860
 0xcff39858 0xcff395d0 0xcff39860 0xcff39c38
 0xcff39c30 0xcff39860 0xcff39c38 0xcff39d80
 0xcff39d78 0xcff39c38 0xcff39d80 0xcff38008
 0xcff38000 0xcff39d80 0xcff38008 0xc0243e40
============================================
/* In fact after some time we came to a happy end. So there was no
   endless loop.
   But let's look at the broken prev pointer again: */

>> walk inode i_list 0xc0243e40 -h n -t -i 5
STRUCT ADDR       PREV   LISTHEAD       NEXT
============================================
          0 0xcff38008 0xc0243e40 0xc5501c38

WARNING: Pointer broken. 0xc579c3e0, SHOULD BE: 0xc0243e40
 0xc5501c30 0xc579c3e0 0xc5501c38 0xc6314f68
 0xc6314f60 0xc5501c38 0xc6314f68 0xc2c44e20
 0xc2c44e18 0xc6314f68 0xc2c44e20 0xc8671340
 0xc8671338 0xc2c44e20 0xc8671340 0xc54da528
 0xc54da520 0xc8671340 0xc54da528 0xcbde6528

WARNING: Iteration threshold reached. Current threshold: 5.
         Use "-i" to change threshold.

/* Walking the other way around everything seems ok: */
>> walk inode i_list 0xc0243e40 -h p -t -i 5
STRUCT ADDR       NEXT   LISTHEAD       PREV
============================================
          0 0xc5501c38 0xc0243e40 0xcff38008
 0xcff38000 0xc0243e40 0xcff38008 0xcff39d80
 0xcff39d78 0xcff38008 0xcff39d80 0xcff39c38
 0xcff39c30 0xcff39d80 0xcff39c38 0xcff39860
 0xcff39858 0xcff39c38 0xcff39860 0xcff395d0
 0xcff395c8 0xcff39860 0xcff395d0 0xcff38e20

WARNING: Iteration threshold reached. Current threshold: 5.
         Use "-i" to change threshold.


>>


Regards,

Andreas

--
Linux for eServer Development
Tel :  +49-7031-16-4640
Notes mail :  Andreas Herrmann/GERMANY/IBM@IBMDE
email :  aherrman@xxxxxxxxxx


<Prev in Thread] Current Thread [Next in Thread>
  • description: walk, Andreas Herrmann <=