参照内核信息的命令

这里介绍用来获取内核内部信息的命令。

bt命令

bt命令输出进程的内核栈的遍历。它是使用频率较高的命令。要显示所有进程的遍历,可以使用下列foreach命令。


crash>foreach bt-tf


当栈上存在具有内核文本符号(text symbol)的地址时,-t选项显示这些符号。在一般的回溯处理失败时可以使用该选项。


crash>bt 839

PID:839 TASK:ffff88001ca82e80 CPU:2 COMMAND:"rsyslogd"

0[ffff88001d8fdd58]schedule at ffffffff8146888f

1[ffff88001d8fde20]do_syslog at ffffffff8104e167

2[ffff88001d8fdea0]kmsg_read at ffffffff81169c80

3[ffff88001d8fdec0]proc_reg_read at ffffffff81160cac

4[ffff88001d8fdf00]vfs_read at ffffffff8111750d

5[ffff88001d8fdf40]sys_read at ffffffff811175ab……

crash>bt-t 839

PID:839 TASK:ffff88001ca82e80 CPU:2 COMMAND:"rsyslogd"

START:schedule at ffffffff8146888f

[ffff88001d8fde20]do_syslog at ffffffff8104e167

[ffff88001d8fde48]autoremove_wake_function at ffffffff81066633

[ffff88001d8fde60]pvclock_clocksource_read at ffffffff8102c275

[ffff88001d8fdea0]kmsg_read at ffffffff81169c80

[ffff88001d8fdec0]proc_reg_read at ffffffff81160cac

[ffff88001d8fdf00]vfs_read at ffffffff8111750d

[ffff88001d8fdf40]sys_read at ffffffff811175ab

……


-f选项显示框架(frame)内的所有栈数据。这个选项可以在确认函数的参数时使用。

-l选项显示文件名和行数。


crash>bt-l 839

PID:839 TASK:ffff88001ca82e80 CPU:2 COMMAND:"rsyslogd"

0[ffff88001d8fdd58]schedule at ffffffff8146888f

/usr/src/debug/kernel-2.6.35.fc14/linux-2.6.35.x86_64/kernel/sched.c:2820#1[ffff88001d8fde20]do_syslog at ffffffff8104e167

/usr/src/debug/kernel-2.6.35.fc14/linux-2.6.35.x86_64/kernel/printk.c:289#2[ffff88001d8fdea0]kmsg_read at ffffffff81169c80

/usr/src/debug/kernel-2.6.35.fc14/linux-2.6.35.x86_64/fs/proc/kmsg.c:39#3[ffff88001d8fdec0]proc_reg_read at ffffffff81160cac

/usr/src/debug/kernel-2.6.35.fc14/linux-2.6.35.x86_64/fs/proc/inode.c:165#4[ffff88001d8fdf00]vfs_read at ffffffff8111750d

/usr/src/debug/kernel-2.6.35.fc14/linux-2.6.35.x86_64/fs/read_write.c:310#5[ffff88001d8fdf40]sys_read at ffffffff811175ab

/usr/src/debug/kernel-2.6.35.fc14/linux-2.6.35.x86_64/fs/read_write.c:388……


-a选项仅显示各CPU上原本正在运行的进程。但是针对运行中的系统(实时内核)启动crash命令时,不支持这个选项。


crash>bt-a

bt:-a option not supported on a live system


小贴士:从5.1.1版开始,当指定-t时,即使是活动系统也会运行。

使用task命令获取栈指针,通过rd-s引用栈区域,就可以得到接近bt-t的信息。


crash>task 839|grep sp

sp0=0xffff88001d8fe000,

sp=0xffff88001d8fdd58,

……

crash>rd 0xffff88001d8fdd58-e 0xffff88001d8fe000-s

……

ffff88001d8fde18:ffff88001d8fde98 do_syslog+0x10f

ffff88001d8fde28:ffff880000000004 ffffffff00000000

ffff88001d8fde38:0000000000000000 ffff88001ca82e80

ffff88001d8fde48:autoremove_wake_function log_wait+0x8

ffff88001d8fde58:log_wait+0x8 pvclock_clocksource_read+0x48

ffff88001d8fde68:00007f96ffffffff 00007f969248b360

ffff88001d8fde78:0000000000000fff ffff88001d8fdf58

ffff88001d8fde88:0000000000000000 0000000000000003

ffff88001d8fde98:ffff88001d8fdeb8 kmsg_read+0x4d

ffff88001d8fdea8:ffff88001b455d80 ffff88001b6cc000

ffff88001d8fdeb8:ffff88001d8fdef8 proc_reg_read+0x73

ffff88001d8fdec8:ffff88001d8fdef8 ffff88001d8fdf58

ffff88001d8fded8:0000000000000fff 00007f969248b360

ffff88001d8fdee8:ffff88001b6cc000 00007f969248b360

ffff88001d8fdef8:ffff88001d8fdf38 vfs_read+0xa9

ffff88001d8fdf08:ffff88001d8fdf18 ffff88001db55000

ffff88001d8fdf18:ffff88001d8fdf38 ffff88001b6cc000

ffff88001d8fdf28:00007f969248b360 00007f968bfff9c0

ffff88001d8fdf38:ffff88001d8fdf78 sys_read+0x4a

……


dev命令

dev命令显示字符设备(character device)的列表。使用-p选项显示PCI设备。它的输出与lspci命令相同。使用-i选项显示I/O端口和I/O内存。内容基本与下列命令相同。


cat/proc/ioports

cat/proc/iomem


dis命令

dis命令是进行反汇编的命令。如果指定-l选项,还会显示源代码名称和行编号。


crash>dis-l schedule

/usr/src/debug/kernel-2.6.35.fc14/linux-2.6.35.x86_64/kernel/sched.c:3813

0xffffffff81468385<schedule>:push%rbp

0xffffffff81468386<schedule+0x1>:mov%rsp,%rbp

0xffffffff81468389<schedule+0x4>:push%r15

0xffffffff8146838b<schedule+0x6>:push%r14

0xffffffff8146838d<schedule+0x8>:push%r13

0xffffffff8146838f<schedule+0xa>:push%r12

0xffffffff81468391<schedule+0xc>:push%rbx

……


files命令

files命令显示进程打开的文件的信息。


crash>fles 1474

PID:1474 TASK:ffff88001c5c9740 CPU:0 COMMAND:"sh"

ROOT:/CWD:/home/hat

FD FILE DENTRY INODE TYPE PATH

0 ffff88001bccd900 ffff88001eb23cc0 ffff88001edfbc30 CHR/dev/tty1

1 ffff88001b655b40 ffff88001d215f00 ffff88001909d1b0 REG/proc/sysrq-trigger

2 ffff88001bccd900 ffff88001eb23cc0 ffff88001edfbc30 CHR/dev/tty1

10 ffff88001bccd900 ffff88001eb23cc0 ffff88001edfbc30 CHR/dev/tty1


irq命令

irq命令显示关于内核内部管理的中断的信息。

kmem命令

显示关于内核的内存使用情况的信息。-s选项显示slab缓存(slab cache)的信息。信息与/proc/slabinfo相同。

参照内核信息的命令 - 图1

-i选项显示内存的整体使用情况。等同于free命令。


crash>kmem-i

PAGES TOTAL PERCENTAGE


参照内核信息的命令 - 图2

使用-p选项显示内存映射。也可以指定地址。[]中的页面表示尚未释放内存。

参照内核信息的命令 - 图3

当引用某个内存发生重大故障时,如果使用-p选项,就可以确认这个内存是已释放还是仍在使用。

list命令

list命令查找在内核中共同使用的list_head结构的链接列表,依次显示列表上的对象(object)。


crash>list modules

ffffffff81a59120

ffffffffa01e7598

……

ffffffffa0007e08

ffffffffa0000828

crash>list modules|wc-l

28

crash>


可以看出modules列表中连接了28个对象。下面是对象中间存在list_head结构的成员的例子。这种情况下使用-o选项指定对象中的list_head结构的位置,同样会查找列表。


crash>struct packet_type.list

struct packet_type{

[0x40]struct list_head list;

}


可以得知list_head结构的offset为0x40,这可以在-o选项中指定。


crash>list-o 0x40 ip_packet_type

ffffffff81b881a0

ffffffff81b85ea0

ffffffff81b85ee0

ffffffff81b85f20

ffffffff81b88720


可以看出ip_packet_type的list成员连接了5个对象。

加上-s选项,这个对象的成员也会同时显示。下面是查找列表并显示各对象的func成员的例子。


crash>list-o 0x40 ip_packet_type-s packet_type.func

ffffffff81b881a0

func=0xffffffff813f109b<ip_rcv>,

ffffffff81b85ea0

func=0xffffffff81b85eb0,

ffffffff81b85ee0

func=0xffffffff81b85ef0,

ffffffff81b85f20

func=0xffffffff81b85f30,

ffffffff81b88720

func=0,


mod命令

mod命令显示内核模块的信息,读入符号信息或调试信息。不指定选项时只显示内核模块信息。使用-s选项指定要读入的内核模块。使用-S选项指定目录,就会尝试从所指定的目录自动检索并读入模块。

参照内核信息的命令 - 图4

net命令

net命令显示网络设备的信息列表。指定显示的net_device结构的地址,使用struct命令进行转储,就可以获取更加详细的信息。


crash>net

NET_DEVICE NAME IP ADDRESS(ES)

ffffffff8030f680 lo 127.0.0.1

ffff81007ea24000 eth2 192.168.0.155

ffff81007f7b8000 eth3 192.168.0.156

ffff81007ebbd000 eth0 172.16.0.153

ffff81007e1ff000 eth1

ffff81007d50a000 sit0

crash>struct net_device ffff81007ea24000

struct net_device{

name="eth2¥00045090668¥000¥000",

name_hist={

next=0x0,

pprev=0xffffffff804bae90

},

……


p命令

向gdb的print命令传递输入时,p命令可以显示结果。


crash>p init_mm

init_mm=$14={

mmap=0x0,

mm_rb={

rb_node=0x0

},

mmap_cache=0x0,

get_unmapped_area=0,

……


输入为CPU个别符号(percpu)时,显示各CPU个别区域的地址。


crash>p x86_bios_cpu_apicid

PER-CPU DATA TYPE:

u16 x86_bios_cpu_apicid;

PER-CPU ADDRESSES:

[0]:ffff88003fc0dc10

[1]:ffff88003fd0dc10


ps命令

ps命令显示进程信息。-a选项显示赋予该进程的命令行变量和环境变量。


crash>ps-a rsyslogd

PID:624 TASK:ffff880037b9dc80 CPU:0 COMMAND:"rsyslogd"

ARG:/sbin/rsyslogd-n-c 5

ENV:PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

LANG=ja_JP.UTF-8

LISTEN_PID=624

LISTEN_FDS=1

SYSLOGD_OPTIONS=-c 5


-t选项显示进程的运行时间、开始时刻、用户空间及内核空间上的执行时间。


crash>ps-t rsyslogd

PID:624 TASK:ffff880037b9dc80 CPU:0 COMMAND:"rsyslogd"

RUN TIME:07:43:23

START TIME:10

UTIME:2

STIME:13


rd命令

rd命令是读取内存内容的命令。本节在ascii命令、bt命令、wr命令的解说中都使用过该命令。

runq命令

runq命令显示连接到进程调度程序的运行队列(run queue)的进程(运行中的进程)。

search命令

search命令检索内存空间中指定的值。


crash>search deadbeef

ffff880011a43dd0:deadbeef

……

ffff88001620add0:deadbeef


使用-c选项也可以检索字符串。


crash>search-c"Linux version"

ffff880001600050:Linux version 2.6.35.11-83.fc14.x86_64(mockbuild@x86-01

……

ffffffff81cebcc7:Linux version 2.6.35.11-83.fc14.x86_64(mockbuild@x86-01


sig命令

sig命令显示进程的信号处理程序。另外,还会显示挂起(pending)的信号信息。-l选项等同于kill-l,显示已定义的信号编号。

struct命令

struct命令根据结构的定义和实际的地址,配合结构显示数据。


crash>struct timespec xtime

struct timespec{

tv_sec=0x492ae39c,

tv_nsec=0x25218473

}


swap命令

swap命令输出交换设备的信息。输出内容与swapon-s基本相同。

sym命令

sym命令是解析符号(symbol)的命令。sym-l与cat System.map相同。

sys命令

sys命令显示系统的信息。显示时刻或CPU的平均负载(load average)、描述出现重大故障原因的信息等。与crash命令启动时显示的信息相同。内核配置CONFIG_IKCONFIG启用时,执行sys config就可以显示内核配置的列表。内容与/proc/config.gz解压缩后的文件相同。


crash>sys confg

#

Automatically generated make config:don't edit

Linux/x86_64 2.6.39 Kernel Configuration

Sun May 29 05:46:04 2011

#

CONFIG_64BIT=y

CONFIG_X86_32 is not set

CONFIG_X86_64=y

CONFIG_X86=y

CONFIG_INSTRUCTION_DECODER=y

CONFIG_OUTPUT_FORMAT="elf64-x86-64"

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"

……


对运行中的(live)系统运行crash命令时,可以使用sys-panic故意引起内核出现重大故障。运行结果与echo c>/proc/sysrq-trigger相同。

task命令

task命令是显示task_struct结构(进程管理所用的数据结构)的命令。

timer命令

timer命令显示加入到计时器列表中的计时器。

whatis命令

whatis命令显示结构等的类型或变量的定义。下面是显示全局变量modules的例子。可以看出modules是list_head结构类型的变量。


crash>whatis modules

struct list_head modules;


wr命令

wr命令是改写内存内容的命令。下例使用crash命令,在运行中的系统上改写表示时间的jiffies变量。改写后,表示从启动开始经过的时间的UPTIME增加了3天以上。


crash>sys

KERNEL:../linux-2.6/vmlinux


参照内核信息的命令 - 图5

小贴士:/proc/kcore和/dev/crash是只读的,因此要使用wr命令必须是/dev/mem。2.6.27版以后的内核在安全对策中引进了CONFIG_STRUCT_DEVMEM,想要使用wr命令时,必须将这个选项设置为off。