NAME
list - linked list
SYNOPSIS
list [[-o] offset] [-e end] [-s struct[.member]] [-H] start
DESCRIPTION
This command dumps the contents of a linked list. The entries in a linked
are typically data structures that are tied together in one of two formats:
1. A starting address points to a data structure; that structure contains
a member that is a pointer to the next structure, and so on. The list
typically ends when a "next" pointer value contains one of the
following:
a. a NULL pointer.
b. a pointer to the start address.
c. a pointer to the first item pointed to by the start address.
d. a pointer to its containing structure.
2. Many Linux lists are linked via embedded list_head structures contained
within the data structures in the list. The linked list is headed by an
external LIST_HEAD, which is simply a list_head structure initialized to
point to itself, signifying that the list is empty:
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
In the case of list_head-type lists, the "next" pointer is the address
of the embedded list_head structure in the next structure, and not the
address of the structure itself. The list typically ends when the
list_head's next pointer points back to the LIST_HEAD address.
This command can handle both types of linked list; in both cases the list
of addresses that are dumped are the addresses of the data structures
themselves.
The arguments are as follows:
[-o] offset The offset within the structure to the "next" pointer
(default is 0). If non-zero, the offset may be entered
in either of two manners:
1. In "structure.member" format; the "-o" is not necessary.
2. A number of bytes; the "-o" is only necessary on processors
where the offset value could be misconstrued as a kernel
virtual address.
-e end If the list ends in a manner unlike the typical manners that
are described above, an explicit ending address value may be
entered.
-s struct For each address in list, format and print as this type of
structure; use the "struct.member" format in order to display
a particular member of the structure.
The meaning of the "start" argument, which can be expressed either
symbolically or in hexadecimal format, depends upon whether the -H option
is pre-pended or not:
start The address of the first structure in the list.
-H start The address of the LIST_HEAD structure, typically expressed
symbolically.
EXAMPLES
Note that each task_struct is linked to its parent's task_struct via the
p_pptr member:
crash> struct task_struct.p_pptr
struct task_struct {
[136] struct task_struct *p_pptr;
}
That being the case, given a task_struct pointer of c169a000, show its
parental hierarchy back to the "init_task" (the "swapper" task):
crash> list task_struct.p_pptr c169a000
c169a000
c0440000
c50d0000
c0562000
c0d28000
c7894000
c6a98000
c009a000
c0252000
Given that the "task_struct.p_pptr" offset is 136 bytes, the same
result could be accomplished like so:
crash> list 136 c169a000
c169a000
c0440000
c50d0000
c0562000
c0d28000
c7894000
c6a98000
c009a000
c0252000
The list of currently-registered file system types are headed up by a
struct file_system_type pointer named "file_systems", and linked by
the "next" field in each file_system_type structure. The following
sequence displays the address and name of each registered file system type:
crash> p file_systems
file_systems = $2 = (struct file_system_type *) 0xc02ebea0
crash> list file_system_type.next -s file_system_type.name 0xc02ebea0
c02ebea0
name = 0xc0280372 "proc",
c02fd4a0
name = 0xc02bf348 "sockfs",
c02eb544
name = 0xc027c25a "tmpfs",
c02eb52c
name = 0xc027c256 "shm",
c02ebbe0
name = 0xc027e054 "pipefs",
c02ec9c0
name = 0xc0283c13 "ext2",
c02ecaa8
name = 0xc0284567 "iso9660",
c02ecc08
name = 0xc0284cf5 "nfs",
c02edc60
name = 0xc028d832 "autofs",
c02edfa0
name = 0xc028e1e0 "devpts"
In some kernels, the system run queue is a linked list headed up by the
"runqueue_head", which is defined like so:
static LIST_HEAD(runqueue_head);
The run queue linking is done with the "run_list" member of the task_struct:
crash> struct task_struct.run_list
struct task_struct {
[60] struct list_head run_list;
}
Therefore, to view the list of task_struct addresses in the run queue,
either of the following commands will work:
crash> list task_struct.run_list -H runqueue_head
f79ac000
f7254000
f7004000
crash> list 60 -H runqueue_head
f79ac000
f7254000
f7004000
Lastly, in some kernel versions, the vfsmount structures of the mounted
filesystems are linked by the LIST_HEAD "vfsmntlist", which uses the
mnt_list list_head of each vfsmount structure in the list. To dump each
vfsmount structure in the list, append the -s option:
crash> list -H vfsmntlist vfsmount.mnt_list -s vfsmount
c3fc9e60
struct vfsmount {
mnt_hash = {
next = 0xc3fc9e60,
prev = 0xc3fc9e60
},
mnt_parent = 0xc3fc9e60,
mnt_mountpoint = 0xc3fc5dc0,
mnt_root = 0xc3fc5dc0,
mnt_instances = {
next = 0xc3f60a74,
prev = 0xc3f60a74
},
mnt_sb = 0xc3f60a00,
mnt_mounts = {
next = 0xf7445e08,
prev = 0xf7445f88
},
mnt_child = {
next = 0xc3fc9e88,
prev = 0xc3fc9e88
},
mnt_count = {
counter = 209
},
mnt_flags = 0,
mnt_devname = 0xc8465b20 "/dev/root",
mnt_list = {
next = 0xf7445f9c,
prev = 0xc02eb828
},
mnt_owner = 0
}
f7445f60
struct vfsmount {
...
|