精华内容
下载资源
问答
  • crash 工具源码

    2018-04-06 16:24:41
    自测可用的crash 工具源码,比如用arm 32位的,make target=arm
  • 使用crash工具看懂slab

    2021-05-14 10:23:29
    原标题:使用crash工具看懂slab参考Linux内核代码: 3.10crash> kmem -S sock_inode_cache>kmem-S-sock_inode_cachecat ./kmem-S-sock_inode_cache struct slab *slab的地址为 ffff8801de2ca000slab->s_mem...

    原标题:使用crash工具看懂slab

    参考Linux内核代码: 3.10

    crash> kmem -S sock_inode_cache>

    kmem-S-sock_inode_cache

    cat ./kmem-S-sock_inode_cache

    e75d7e13033517a324e0071b40a81d48.png

    struct slab *slab的地址为 ffff8801de2ca000

    slab->s_mem的地址为 0xffff8801de2ca080

    crash> struct slab ffff8801de2ca000

    struct slab {

    nodeid = 0

    s_mem = 0xffff8801de2ca080,(指向第一个object)

    ..

    }

    可以看到上面的slab在节点0上,有6个object. 其中有三个是share cache,说明是给本节点上所有cpu公用,其中有一个在cpu4上。另外两个还未指定用途。

    ffff8801de2ca080 (shared cache)

    ffff8801de2ca300

    ffff8801de2ca580(cpu 4 cache)

    ffff8801de2ca800 (shared cache)

    ffff8801de2caa80

    ffff8801de2cad00 (shared cache)

    上面的struct slab结构挂在kmem_list3结构的slabs_partial、slabs_full或者slabs_free链表上。

    struct kmem_list3 {

    struct list_head slabs_partial;

    struct list_head slabs_full;

    struct list_head slabs_free;

    ...

    }

    先看看这个cpu4上的object,既然这个是在cpu4上的object,看看是否能在cpu4上的 sock_inode_cache缓存找到这个object ffff8801de2ca580

    然后再找出(ffff8801de2ca080 (shared cache))。

    找出这两个值,就知道slab到底是怎么回事了。

    struct kmem_cache {

    /* 1) per-cpu data, touched during every alloc/free */

    struct array_cache *array[NR_CPUS];

    const char *name;

    struct list_head next;

    ...

    struct kmem_list3 *nodelists

    [MAX_NUMNODES];

    }

    crash> struct kmem_cache

    struct kmem_cache {

    ....

    name = 0xffffffff817d2db7 "sock_inode_cache",

    next = {

    },

    }

    struct array_cache {

    unsigned int avail;

    ..

    void *entry[]; /*

    }

    可以看到entry是一个指针数组,数组里面每一个元素就是本cpu上一个object的值。

    crash> struct array_cache

    struct array_cache {

    }

    输出0x10个object, 发现第一个值就是 ffff88023f5ff580,

    ffff881020843418: ffff88023f5ff580 ffff88107f4ffd00

    ffff881020843428: ffff8801bc2bd0c0 ffff880e5d3c00c0

    ffff881020843438: ffff8806a7453d40 ffff880209cfcac0

    crash> struct kmem_list3

    struct kmem_list3 {

    slabs_partial = {

    slabs_full = {

    slabs_free = {

    ...

    },

    ...

    }

    crash> struct array_cache

    struct array_cache {

    }

    同样的entry数组中的每个值就是本节点上share cache Object.

    在59行看到

    (ffff8801de2ca080(sharedcache))

    Line58 ffff8810208443a8: ffff8802ec1165c0

    ffff88107f554800

    Line59ffff8810208443b8: ffff8801de2ca080

    ffff8804b1641340

    Note: linux在3.12以后去掉了struct slab结构,但是原理没什么变化。 返回搜狐,查看更多

    责任编辑:

    展开全文
  • 本文主要介绍linux下crash工具常用命令的功能和使用。背景知识crash是redhat的工程师开发的,主要用来离线分析linux内核转存文件,它整合了gdb工具,功能非常强大。可以查看堆栈,dmesg日志,内核数据结构,反汇编...

    工欲善其事,必先利其器。本文主要介绍linux下crash工具常用命令的功能和使用。

    背景知识

    crash是redhat的工程师开发的,主要用来离线分析linux内核转存文件,它整合了gdb工具,功能非常强大。可以查看堆栈,dmesg日志,内核数据结构,反汇编等等。crash支持多种工具生成的转存文件格式,如kdump,LKCD,netdump和diskdump,而且还可以分析虚拟机Xen和Kvm上生成的内核转存文件。同时crash还可以调试运行时系统,直接运行crash即可,ubuntu下内核映象存放在/proc/kcore。

    ad03152a0a53

    运行时系统调试

    crash和linux内核是紧密耦合的,会随着内核的变化持续更新,它向前兼容的,新的crash工具可以分析老内核的转存文件。如果你的内核版本较新,crash无法解析,可以尝试安装最新的crash工具。

    常用命令

    下面介绍常用命令的使用,主要参考了crash_whitepaper和crash工具自带的帮助文档。crash_whitepaper介绍了开发的初衷,编译,命令的分类和使用以及如何添加自己的命令,是一个非常好的参考文献。我用的版本是crash-7.2.6和gdb-7.6,使用时可以使用“help command”来查看详细的帮助文档,详细的命令列表见附件。

    ad03152a0a53

    帮助文档

    crash在加载内核转存文件是会输出系统基本信息,如出问题的进程(bash - 2613),系统内存大小(7.9GB),系统架构(x86_64)等等,可以看到这个dump是sysrq触发的一个panic系统崩溃。

    KERNEL: ../kernel-src/linux-4.19.53/vmlinux

    DUMPFILE: crash/201907070732/dump.201907070732 [PARTIAL DUMP]

    CPUS: 4

    DATE: Sun Jul 7 07:31:34 2019

    UPTIME: 00:10:27

    LOAD AVERAGE: 0.14, 0.16, 0.12

    TASKS: 584

    NODENAME: glbian-OptiPlex-990

    RELEASE: 4.19.53

    VERSION: #1 SMP Sun Jun 23 11:01:25 CST 2019

    MACHINE: x86_64 (3292 Mhz)

    MEMORY: 7.9 GB

    PANIC: "sysrq: SysRq : Trigger a crash"

    PID: 2613

    COMMAND: "bash"

    TASK: ffff8b7df3cdae00 [THREAD_INFO: ffff8b7df3cdae00]

    CPU: 2

    STATE: TASK_RUNNING (SYSRQ)

    查看堆栈

    一般可以先查看堆栈(bt),看看系统死在什么地方,进而确定调查方向。可以看到这个dump的异常发生在sysrq的处理函数里面。

    crash> bt

    PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    '#0 [ffffa0f442cd7a08] machine_kexec at ffffffff99a69313

    '#1 [ffffa0f442cd7a68] __crash_kexec at ffffffff99b3e6b9

    '#2 [ffffa0f442cd7b30] crash_kexec at ffffffff99b3f441

    '#3 [ffffa0f442cd7b50] oops_end at ffffffff99a32bed

    '#4 [ffffa0f442cd7b78] no_context at ffffffff99a7997c

    '#5 [ffffa0f442cd7bd8] __bad_area_nosemaphore at ffffffff99a79d15

    '#6 [ffffa0f442cd7c20] bad_area at ffffffff99a79f86

    '#7 [ffffa0f442cd7c48] __do_page_fault at ffffffff99a7a486

    '#8 [ffffa0f442cd7cc0] do_page_fault at ffffffff99a7a60d

    '#9 [ffffa0f442cd7cf0] page_fault at ffffffff9a6010ae

    [exception RIP: sysrq_handle_crash+22]

    RIP: ffffffff9a034066 RSP: ffffa0f442cd7da8 RFLAGS: 00010286

    RAX: ffffffff9a034050 RBX: 0000000000000063 RCX: 0000000000000006

    RDX: 0000000000000000 RSI: 0000000000000096 RDI: 0000000000000063

    RBP: ffffa0f442cd7da8 R8: 00000000000002f2 R9: 0000000000000007

    R10: 0000000000000000 R11: ffffffff9b39c3ed R12: 0000000000000004

    R13: 0000000000000000 R14: ffffffff9afa7300 R15: ffff8b7de5af9100

    ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018

    '#10 [ffffa0f442cd7db0] __handle_sysrq at ffffffff9a0347e8

    '#11 [ffffa0f442cd7de0] write_sysrq_trigger at ffffffff9a034cbf

    ... ...

    另外可以加参数显示函数偏移,函数所在的文件和每一帧的具体内容,从而对照源码和汇编代码,查看函数入参和局部变量。

    crash> bt -slf

    PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    '#0 [ffffa0f442cd7a08] machine_kexec+451 at ffffffff99a69313

    /home/glbian/data/kernel-src/linux-4.19.53/arch/x86/kernel/machine_kexec_64.c: 346

    ffffa0f442cd7a10: 0000a0f442cd7a50 ffff8b7c40000000

    ffffa0f442cd7a20: 0000000024001000 ffff8b7c64001000

    ffffa0f442cd7a30: 0000000024000000 a05cedc0dfb99200

    ffffa0f442cd7a40: a05cedc0dfb99200 ffffa0f442cd7cf8

    ffffa0f442cd7a50: 0000000000000009 ffffa0f442cd7cf8

    ffffa0f442cd7a60: ffffa0f442cd7b28 ffffffff99b3e6b9

    ... ...

    ’#8 [ffffa0f442cd7cc0] do_page_fault+45 at ffffffff99a7a60d

    /home/glbian/data/kernel-src/linux-4.19.53/arch/x86/mm/fault.c: 1470

    ffffa0f442cd7cc8: ffff8b7e6500d140 0000000000000000

    ffffa0f442cd7cd8: 0000000000000000 0000000000000000

    ffffa0f442cd7ce8: ffffa0f442cd7cf9 ffffffff9a6010ae

    '#9 [ffffa0f442cd7cf0] page_fault+30 at ffffffff9a6010ae

    /home/glbian/data/kernel-src/linux-4.19.53/arch/x86/entry/entry_64.S: 1181

    [exception RIP: sysrq_handle_crash+22]

    RIP: ffffffff9a034066 RSP: ffffa0f442cd7da8 RFLAGS: 00010286

    RAX: ffffffff9a034050 RBX: 0000000000000063 RCX: 0000000000000006

    RDX: 0000000000000000 RSI: 0000000000000096 RDI: 0000000000000063

    RBP: ffffa0f442cd7da8 R8: 00000000000002f2 R9: 0000000000000007

    R10: 0000000000000000 R11: ffffffff9b39c3ed R12: 0000000000000004

    R13: 0000000000000000 R14: ffffffff9afa7300 R15: ffff8b7de5af9100

    ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018

    /home/glbian/data/kernel-src/linux-4.19.53/drivers/tty/sysrq.c: 147

    ffffa0f442cd7cf8: ffff8b7de5af9100 ffffffff9afa7300

    ffffa0f442cd7d08: 0000000000000000 0000000000000004

    ffffa0f442cd7d18: ffffa0f442cd7da8 0000000000000063

    ffffa0f442cd7d28: ffffffff9b39c3ed 0000000000000000

    ffffa0f442cd7d38: 0000000000000007 00000000000002f2

    ffffa0f442cd7d48: ffffffff9a034050 0000000000000006

    ffffa0f442cd7d58: 0000000000000000 0000000000000096

    ffffa0f442cd7d68: 0000000000000063 ffffffffffffffff

    ffffa0f442cd7d78: ffffffff9a034066 0000000000000010

    ffffa0f442cd7d88: 0000000000010286 ffffa0f442cd7da8

    ffffa0f442cd7d98: 0000000000000018 0000000000000000

    ffffa0f442cd7da8: ffffa0f442cd7dd8 ffffffff9a0347e8

    '#10 [ffffa0f442cd7db0] __handle_sysrq+136 at ffffffff9a0347e8

    /home/glbian/data/kernel-src/linux-4.19.53/drivers/tty/sysrq.c: 583

    ffffa0f442cd7db8: 0000000000000002 fffffffffffffffb

    ffffa0f442cd7dc8: ffffa0f442cd7ee8 0000563d45717780

    ffffa0f442cd7dd8: ffffa0f442cd7df0 ffffffff9a034cbf

    ... ...

    可以用dis命令进行返汇编,查看对应地址的代码逻辑。

    >crash> dis -r ffffffff9a6010ae

    0xffffffff9a601090 : data32 xchg %ax,%ax

    0xffffffff9a601093 : callq 0xffffffff9a601230

    0xffffffff9a601098 : mov %rsp,%rdi

    0xffffffff9a60109b : mov 0x78(%rsp),%rsi

    0xffffffff9a6010a0 : movq $0xffffffffffffffff,0x78(%rsp)

    0xffffffff9a6010a9 : callq 0xffffffff99a7a5e0

    0xffffffff9a6010ae : jmpq 0xffffffff9a601330

    >crash> dis -f ffffffff9a6010ae

    0xffffffff9a6010ae : jmpq 0xffffffff9a601330

    0xffffffff9a6010b3 : nopl (%rax)

    0xffffffff9a6010b6 : nopw %cs:0x0(%rax,%rax,1)

    有时会出现堆栈被破坏的情况,可以用-t/-T来把整个stack的信息dump出来,往往可以看到一些蛛丝马迹。

    crash> bt -t

    PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    START: machine_kexec at ffffffff99a69313

    [ffffa0f442cd7a08] machine_kexec at ffffffff99a69313

    [ffffa0f442cd7a68] __crash_kexec at ffffffff99b3e6b9

    [ffffa0f442cd7ac0] sysrq_handle_crash at ffffffff9a034050

    [ffffa0f442cd7af0] sysrq_handle_crash at ffffffff9a034066

    [ffffa0f442cd7b30] crash_kexec at ffffffff99b3f441

    [ffffa0f442cd7b38] __die at ffffffff99a33375

    [ffffa0f442cd7b50] oops_end at ffffffff99a32bed

    [ffffa0f442cd7b78] no_context at ffffffff99a7997c

    [ffffa0f442cd7bd8] __bad_area_nosemaphore at ffffffff99a79d15

    [ffffa0f442cd7c20] bad_area at ffffffff99a79f86

    [ffffa0f442cd7c48] __do_page_fault at ffffffff99a7a486

    [ffffa0f442cd7cc0] do_page_fault at ffffffff99a7a60d

    [ffffa0f442cd7cf0] page_fault at ffffffff9a6010ae

    [ffffa0f442cd7d48] sysrq_handle_crash at ffffffff9a034050

    [ffffa0f442cd7d78] sysrq_handle_crash at ffffffff9a034066

    [ffffa0f442cd7db0] __handle_sysrq at ffffffff9a0347e8

    [ffffa0f442cd7de0] write_sysrq_trigger at ffffffff9a034cbf

    [ffffa0f442cd7df8] proc_reg_write at ffffffff99d2a0ee

    [ffffa0f442cd7e18] __vfs_write at ffffffff99ca8a0a

    [ffffa0f442cd7e40] apparmor_file_permission at ffffffff99e53a0a

    [ffffa0f442cd7e50] security_file_permission at ffffffff99e06cf1

    [ffffa0f442cd7e78] _cond_resched at ffffffff9a4153f9

    [ffffa0f442cd7ea0] vfs_write at ffffffff99ca8d11

    [ffffa0f442cd7ed8] ksys_write at ffffffff99ca8fcc

    [ffffa0f442cd7f20] __x64_sys_write at ffffffff99ca906a

    [ffffa0f442cd7f30] do_syscall_64 at ffffffff99a0428a

    [ffffa0f442cd7f50] entry_SYSCALL_64_after_hwframe at ffffffff9a600088

    RIP: 00007ff47e1ef154 RSP: 00007ffee9226298 RFLAGS: 00000246

    RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007ff47e1ef154

    RDX: 0000000000000002 RSI: 0000563d45717780 RDI: 0000000000000001

    RBP: 0000563d45717780 R8: 000000000000000a R9: 0000000000000001

    R10: 000000000000000a R11: 0000000000000246 R12: 00007ff47e4cb760

    R13: 0000000000000002 R14: 00007ff47e4c72a0 R15: 00007ff47e4c6760

    ORIG_RAX: 0000000000000001 CS: 0033 SS: 002b

    默认bt会dump问题线程的场景,还可以用bt -a/-c查看所有当前CPU或指定cpu的堆栈。

    crash> bt -c 1

    PID: 0 TASK: ffff8b7e64165c00 CPU: 1 COMMAND: "swapper/1"

    '#0 [fffffe0000034e38] crash_nmi_callback at ffffffff99a5d3d7

    '#1 [fffffe0000034e48] nmi_handle at ffffffff99a33691

    ... ...

    '#12 [ffffa0f440cd7f50] secondary_startup_64 at ffffffff99a000d4

    crash> bt -a

    PID: 0 TASK: ffffffff9ae13740 CPU: 0 COMMAND: "swapper/0"

    ... ...

    PID: 0 TASK: ffff8b7e64165c00 CPU: 1 COMMAND: "swapper/1"

    ... ...

    PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    ... ...

    PID: 0 TASK: ffff8b7e642c4500 CPU: 3 COMMAND: "swapper/3"

    ... ...

    也可以用set命令来改变线程环境,从而查看别的cpu上的堆栈情况。

    crash> set 1

    PID: 1

    COMMAND: "systemd"

    TASK: ffff8b7e6413c500 [THREAD_INFO: ffff8b7e6413c500]

    CPU: 3

    STATE: TASK_INTERRUPTIBLE

    crash> bt

    PID: 1 TASK: ffff8b7e6413c500 CPU: 3 COMMAND: "systemd"

    '#0 [ffffa0f440c6fce0] __schedule at ffffffff9a414ba7

    '#1 [ffffa0f440c6fd80] schedule at ffffffff9a41519c

    '#2 [ffffa0f440c6fd90] schedule_hrtimeout_range_clock at ffffffff9a419691

    '#3 [ffffa0f440c6fe20] schedule_hrtimeout_range at ffffffff9a4196b3

    '#4 [ffffa0f440c6fe30] ep_poll at ffffffff99cf8941

    '#5 [ffffa0f440c6fee0] do_epoll_wait at ffffffff99cf8ae0

    '#6 [ffffa0f440c6ff20] __x64_sys_epoll_wait at ffffffff99cf8b0e

    '#7 [ffffa0f440c6ff30] do_syscall_64 at ffffffff99a0428a

    '#8 [ffffa0f440c6ff50] entry_SYSCALL_64_after_hwframe at ffffffff9a600088

    RIP: 00007ffa791c6bb7 RSP: 00007ffc1c00b9d0 RFLAGS: 00000293

    RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007ffa791c6bb7

    RDX: 00000000000000eb RSI: 00007ffc1c00ba10 RDI: 0000000000000004

    RBP: 00007ffc1c00ba10 R8: 0000000000000000 R9: 7465677261742e79

    R10: 00000000ffffffff R11: 0000000000000293 R12: 00000000000000eb

    R13: 00000000ffffffff R14: 00007ffc1c00ba10 R15: 0000000000000001

    ORIG_RAX: 00000000000000e8 CS: 0033 SS: 002b

    系统日志

    log命令可以用来查看系统的日志,“log -a”可以读取还没有从内核日志缓存到用户空间日志缓存的日志。

    也可以重定向到文件(log > logfile)。

    crash> log

    ... ...

    [ 1610.759133] sysrq: SysRq : Trigger a crash

    [ 1610.759147] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000

    [ 1610.759150] PGD 0 P4D 0

    [ 1610.759154] Oops: 0002 [#1] SMP PTI

    [ 1610.759159] CPU: 2 PID: 2613 Comm: bash Kdump: loaded Not tainted 4.19.53 #1

    [ 1610.759161] Hardware name: Dell Inc. OptiPlex 990/0RVG2C, BIOS A13 04/02/2012

    [ 1610.759167] RIP: 0010:sysrq_handle_crash+0x16/0x20

    [ 1610.759170] Code: e8 9f fb ff ff e9 c0 fe ff ff 90 90 90 90 90 90 90 90 90 90 66 66 66 66 90 55 48 89 e5 c7 05 85 10 36 01 01 00 00 00 0f ae f8 04 25 00 00 00 00 01 5d c3 66 66 66 66 90 55 c7 05 40 fa e2 00

    [ 1610.759173] RSP: 0018:ffffa0f442cd7da8 EFLAGS: 00010286

    [ 1610.759176] RAX: ffffffff9a034050 RBX: 0000000000000063 RCX: 0000000000000006

    [ 1610.759178] RDX: 0000000000000000 RSI: 0000000000000096 RDI: 0000000000000063

    [ 1610.759180] RBP: ffffa0f442cd7da8 R08: 00000000000002f2 R09: 0000000000000007

    [ 1610.759182] R10: 0000000000000000 R11: ffffffff9b39c3ed R12: 0000000000000004

    [ 1610.759184] R13: 0000000000000000 R14: ffffffff9afa7300 R15: ffff8b7de5af9100

    [ 1610.759186] FS: 00007ff47eb0a740(0000) GS:ffff8b7e65880000(0000) knlGS:0000000000000000

    [ 1610.759189] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033

    [ 1610.759191] CR2: 0000000000000000 CR3: 0000000205db0003 CR4: 00000000000606e0

    [ 1610.759193] Call Trace:

    [ 1610.759199] __handle_sysrq+0x88/0x140

    [ 1610.759203] write_sysrq_trigger+0x2f/0x40

    [ 1610.759208] proc_reg_write+0x3e/0x60

    [ 1610.759212] __vfs_write+0x3a/0x190

    [ 1610.759216] ? apparmor_file_permission+0x1a/0x20

    [ 1610.759220] ? security_file_permission+0x31/0xc0

    [ 1610.759224] ? _cond_resched+0x19/0x40

    [ 1610.759226] vfs_write+0xb1/0x1a0

    [ 1610.759229] ksys_write+0x5c/0xe0

    [ 1610.759232] __x64_sys_write+0x1a/0x20

    [ 1610.759237] do_syscall_64+0x5a/0x120

    [ 1610.759241] entry_SYSCALL_64_after_hwframe+0x44/0xa9

    [ 1610.759245] RIP: 0033:0x7ff47e1ef154

    [ 1610.759247] Code: 89 02 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 8d 05 b1 07 2e 00 8b 00 85 c0 75 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 f3 c3 66 90 41 54 55 49 89 d4 53 48 89 f5

    [ 1610.759249] RSP: 002b:00007ffee9226298 EFLAGS: 00000246 ORIG_RAX: 0000000000000001

    [ 1610.759252] RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 00007ff47e1ef154

    [ 1610.759254] RDX: 0000000000000002 RSI: 0000563d45717780 RDI: 0000000000000001

    [ 1610.759256] RBP: 0000563d45717780 R08: 000000000000000a R09: 0000000000000001

    [ 1610.759258] R10: 000000000000000a R11: 0000000000000246 R12: 00007ff47e4cb760

    [ 1610.759260] R13: 0000000000000002 R14: 00007ff47e4c72a0 R15: 00007ff47e4c6760

    [ 1610.759263] Modules linked in: nls_iso8859_1 intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_hda_codec_hdmi snd_hda_codec_realtek snd_hda_codec_generic pcbc aesni_intel snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep aes_x86_64 snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi input_leds crypto_simd cryptd snd_seq snd_seq_device snd_timer dcdbas snd glue_helper intel_cstate intel_rapl_perf lpc_ich serio_raw soundcore sch_fq_codel mei_me mei mac_hid parport_pc ppdev lp parport ip_tables x_tables autofs4 hid_generic usbhid hid uas usb_storage i915 kvmgt vfio_mdev mdev vfio_iommu_type1 vfio kvm irqbypass i2c_algo_bit cec rc_core drm_kms_helper psmouse syscopyarea sysfillrect video sysimgblt fb_sys_fops ahci drm libahci e1000e

    [ 1610.759320] CR2: 0000000000000000

    查看数据结构

    struct和union可以用来查看结构体和共用体,用法相同,下面看一些struct

    打印的例子。把指定地址的内容以task_struct结构体解析打印,如果不带地址会显示结构体定义和大小。

    1 打印task_struct结构体

    crash> task_struct ffff8b7df3cdae00 -x

    struct task_struct {

    thread_info = {

    flags = 0x80000000,

    status = 0x0

    },

    state = 0x0,

    stack = 0xffffa0f442cd4000,

    usage = {

    counter = 0x2

    },

    ... ...

    2 打印task_struct定义和大小。

    struct task_struct {

    [0x0] struct thread_info thread_info;

    [0x10] volatile long state;

    [0x18] void *stack;

    ... ...

    [0x1288] void *security;

    [0x12c0] struct thread_struct thread;

    }

    SIZE: 0x23c0

    3 查看成员变量

    crash> task_struct.stack_refcount ffff8b7df3cdae00 -xo

    struct task_struct {

    [ffff8b7df3cdc080] atomic_t stack_refcount;

    }

    4 查看指针成员变量

    crash> task_struct.mm ffff8b7df3cdae00

    mm = 0xffff8b7e5af06600

    crash> task_struct.mm ffff8b7df3cdae00 -p

    struct mm_struct *mm = 0xffff8b7e5af06600

    -> {

    {

    mmap = 0xffff8b7dec0520c8,

    mm_rb = {

    rb_node = 0xffff8b7dec003b78

    },

    vmacache_seqnum = 17,

    get_unmapped_area = 0xffffffff99a35760,

    此外还可以查看数组内容,per-cpu变量,以及其他一些功能,详细可参考帮助文档。

    查看和搜索内存

    除了打印数据结构,有时需要查看和搜索内存内容,看有没有制定的数据模式。

    1 查看系统版本信息

    crash> rd -a linux_banner

    ffffffff9aa00100: Linux version 4.19.53 (glbian@glbian-OptiPlex-990) (gcc vers

    ffffffff9aa0013c: ion 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #1 SMP Sun Jun 23

    ffffffff9aa00178: 11:01:25 CST 2019

    查看内存内容

    crash> rd ffffa0f442cd7a08 32

    ffffa0f442cd7a08: ffffffff99a69313 0000a0f442cd7a50 ........Pz.B....

    ffffa0f442cd7a18: ffff8b7c40000000 0000000024001000 ...@|......

    math?formula=....%20ffffa0f442cd7a28%3A%20ffff8b7c64001000%200000000024000000%20...d%7C..........

    ffffa0f442cd7a38: a05cedc0dfb99200 a05cedc0dfb99200 ..............

    ffffa0f442cd7a48: ffffa0f442cd7cf8 0000000000000009 .|.B............

    ffffa0f442cd7a58: ffffa0f442cd7cf8 ffffa0f442cd7b28 .|.B....({.B....

    ffffa0f442cd7a68: ffffffff99b3e6b9 ffff8b7de5af9100 ............}...

    ffffa0f442cd7a78: ffffffff9afa7300 0000000000000000 .s..............

    ffffa0f442cd7a88: 0000000000000004 ffffa0f442cd7da8 .........}.B....

    ffffa0f442cd7a98: 0000000000000063 ffffffff9b39c3ed c.........9.....

    ffffa0f442cd7aa8: 0000000000000000 0000000000000007 ................

    ffffa0f442cd7ab8: 00000000000002f2 ffffffff9a034050 ........P@......

    ffffa0f442cd7ac8: 0000000000000006 0000000000000000 ................

    ffffa0f442cd7ad8: 0000000000000096 0000000000000063 ........c.......

    ffffa0f442cd7ae8: ffffffffffffffff ffffffff9a034066 ........f@......

    ffffa0f442cd7af8: 0000000000000010 0000000000010286 ................

    3 打印符号表

    crash> rd ffffa0f442cd7a08 32 -s

    ffffa0f442cd7a08: machine_kexec+451 0000a0f442cd7a50

    ffffa0f442cd7a18: ffff8b7c40000000 0000000024001000

    ffffa0f442cd7a28: ffff8b7c64001000 0000000024000000

    ffffa0f442cd7a38: a05cedc0dfb99200 a05cedc0dfb99200

    ffffa0f442cd7a48: ffffa0f442cd7cf8 0000000000000009

    ffffa0f442cd7a58: ffffa0f442cd7cf8 ffffa0f442cd7b28

    ffffa0f442cd7a68: __crash_kexec+105 ffff8b7de5af9100

    ffffa0f442cd7a78: sysrq_crash_op 0000000000000000

    ffffa0f442cd7a88: 0000000000000004 ffffa0f442cd7da8

    ffffa0f442cd7a98: 0000000000000063 text.45672+13

    ffffa0f442cd7aa8: 0000000000000000 0000000000000007

    ffffa0f442cd7ab8: 00000000000002f2 sysrq_handle_crash

    ffffa0f442cd7ac8: 0000000000000006 0000000000000000

    ffffa0f442cd7ad8: 0000000000000096 0000000000000063

    ffffa0f442cd7ae8: ffffffffffffffff sysrq_handle_crash+22

    ffffa0f442cd7af8: 0000000000000010 0000000000010286

    4 查看指定内存区域内容

    crash> rd ffffa0f442cd7a08 -e ffffa0f442cd7a68

    ffffa0f442cd7a08: ffffffff99a69313 0000a0f442cd7a50 ........Pz.B....

    ffffa0f442cd7a18: ffff8b7c40000000 0000000024001000 ...@|......

    math?formula=....%20ffffa0f442cd7a28%3A%20ffff8b7c64001000%200000000024000000%20...d%7C..........

    ffffa0f442cd7a38: a05cedc0dfb99200 a05cedc0dfb99200 ..............

    ffffa0f442cd7a48: ffffa0f442cd7cf8 0000000000000009 .|.B............

    ffffa0f442cd7a58: ffffa0f442cd7cf8 ffffa0f442cd7b28 .|.B....({.B....

    5 搜索指定内存

    crash> search -s ffffa0f442cd7a08 -e ffffa0f442cd7db0 ffffffff9b39c3ed

    ffffa0f442cd7aa0: ffffffff9b39c3ed

    ffffa0f442cd7d28: ffffffff9b39c3ed

    6 搜索匹配数据

    crash> search -p babe0000 -m ffff

    1c4cc6530: babec685

    21f7d35b8: babe4550

    crash>

    查看线程状态

    1 查看所有线程状态

    crash> ps

    PID PPID CPU TASK ST %MEM VSZ RSS COMM

    0 0 0 ffffffff9ae13740 RU 0.0 0 0 [swapper/0]

    0 0 1 ffff8b7e64165c00 RU 0.0 0 0 [swapper/1]

    0 0 2 ffff8b7e64162e00 RU 0.0 0 0 [swapper/2]

    0 0 3 ffff8b7e642c4500 RU 0.0 0 0 [swapper/3]

    1 0 3 ffff8b7e6413c500 IN 0.1 225916 9716 systemd

    2 0 2 ffff8b7e64138000 IN 0.0 0 0 [kthreadd]

    2 查看父线程树

    crash> ps -p 2613

    PID: 0 TASK: ffffffff9ae13740 CPU: 0 COMMAND: "swapper/0"

    PID: 1 TASK: ffff8b7e6413c500 CPU: 3 COMMAND: "systemd"

    PID: 1081 TASK: ffff8b7e5dc81700 CPU: 1 COMMAND: "gdm3"

    PID: 2114 TASK: ffff8b7e584f2e00 CPU: 0 COMMAND: "gdm-session-wor"

    PID: 2136 TASK: ffff8b7e63cc4500 CPU: 1 COMMAND: "gdm-x-session"

    PID: 2149 TASK: ffff8b7e5dfaae00 CPU: 0 COMMAND: "gnome-session-b"

    PID: 2254 TASK: ffff8b7e5e04dc00 CPU: 0 COMMAND: "gnome-shell"

    PID: 2582 TASK: ffff8b7dec3bae00 CPU: 0 COMMAND: "terminator"

    PID: 2592 TASK: ffff8b7dec05ae00 CPU: 1 COMMAND: "bash"

    PID: 2611 TASK: ffff8b7df3f8ae00 CPU: 0 COMMAND: "sudo"

    PID: 2612 TASK: ffff8b7dec3b9700 CPU: 3 COMMAND: "su"

    PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    3 查看子线程

    crash> ps -c 2582

    PID: 2582 TASK: ffff8b7dec3bae00 CPU: 0 COMMAND: "terminator"

    PID: 2592 TASK: ffff8b7dec05ae00 CPU: 1 COMMAND: "bash"

    PID: 2600 TASK: ffff8b7df3f88000 CPU: 0 COMMAND: "bash"

    PID: 2787 TASK: ffff8b7df9f80000 CPU: 3 COMMAND: "bash"

    4 查看线程运行时间

    crash> ps -t 2613

    PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    RUN TIME: 00:00:00

    START TIME: 1296209749767

    UTIME: 36000000

    STIME: 16000000

    5 查看活动线程

    crash> ps -A

    PID PPID CPU TASK ST %MEM VSZ RSS COMM

    0 0 0 ffffffff9ae13740 RU 0.0 0 0 [swapper/0]

    0 0 1 ffff8b7e64165c00 RU 0.0 0 0 [swapper/1]

    0 0 3 ffff8b7e642c4500 RU 0.0 0 0 [swapper/3]

    2613 2612 2 ffff8b7df3cdae00 RU 0.0 28708 4352 bash

    6 查看内核线程

    crash> ps -k

    PID PPID CPU TASK ST %MEM VSZ RSS COMM

    0 0 0 ffffffff9ae13740 RU 0.0 0 0 [swapper/0]

    0 0 1 ffff8b7e64165c00 RU 0.0 0 0 [swapper/1]

    0 0 2 ffff8b7e64162e00 RU 0.0 0 0 [swapper/2]

    0 0 3 ffff8b7e642c4500 RU 0.0 0 0 [swapper/3]

    2 0 2 ffff8b7e64138000 IN 0.0 0 0 [kthreadd]

    7 查看用户态线程

    crash> ps -u

    PID PPID CPU TASK ST %MEM VSZ RSS COMM

    1 0 3 ffff8b7e6413c500 IN 0.1 225916 9716 systemd

    298 1 3 ffff8b7e5879c500 IN 0.4 126508 38028 systemd-journal

    318 1 0 ffff8b7e584f5c00 IN 0.1 48004 6360 systemd-udevd

    822 1 2 ffff8b7e59c71700 IN 0.1 70756 6176 systemd-resolve

    824 1 2 ffff8b7e586e5c00 IN 0.1 146108 5540 systemd-timesyn

    834 1 3 ffff8b7e63881700 IN 0.1 146108 5540 sd-resolve

    863 1 3 ffff8b7e5d790000 IN 0.1 51612 6112 dbus-daemon

    864 1 1 ffff8b7e5d794500 IN 0.1 427264 9404 ModemManager

    8 查看最后运行时间戳

    crash> ps -l

    [1610759003323] [IN] PID: 2582 TASK: ffff8b7dec3bae00 CPU: 0 COMMAND: "terminator"

    [1610758998404] [ID] PID: 211 TASK: ffff8b7e585aae00 CPU: 3 COMMAND: "kworker/u32:5"

    [1610758938747] [RU] PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    [1610758009873] [IN] PID: 2587 TASK: ffff8b7e06cd5c00 CPU: 2 COMMAND: "gdbus"

    crash> ps -m

    [0 00:00:00.000] [IN] PID: 2582 TASK: ffff8b7dec3bae00 CPU: 0 COMMAND: "terminator"

    [0 00:00:00.000] [ID] PID: 211 TASK: ffff8b7e585aae00 CPU: 3 COMMAND: "kworker/u32:5"

    [0 00:00:00.000] [RU] PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    [0 00:00:00.000] [IN] PID: 2587 TASK: ffff8b7e06cd5c00 CPU: 2 COMMAND: "gdbus"

    [0 00:00:00.001] [IN] PID: 2138 TASK: ffff8b7e26801700 CPU: 0 COMMAND: "Xorg"

    9 查看线程资源限制

    crash> ps -r 2613

    PID: 2613 TASK: ffff8b7df3cdae00 CPU: 2 COMMAND: "bash"

    RLIMIT CURRENT MAXIMUM

    CPU (unlimited) (unlimited)

    FSIZE (unlimited) (unlimited)

    DATA (unlimited) (unlimited)

    STACK 8388608 (unlimited)

    CORE 0 (unlimited)

    RSS (unlimited) (unlimited)

    NPROC 30393 30393

    NOFILE 1024 1048576

    MEMLOCK 16777216 16777216

    AS (unlimited) (unlimited)

    LOCKS (unlimited) (unlimited)

    SIGPENDING 30393 30393

    MSGQUEUE 819200 819200

    NICE 0 0

    RTPRIO 0 0

    RTTIME (unlimited) (unlimited)

    Context切换

    有些命令是线程上线文相关的,比如bt,可以用set命令来进行线程上下文切换。

    1 切换到指定线程

    crash> set ffff8b7e6413c500

    PID: 1

    COMMAND: "systemd"

    TASK: ffff8b7e6413c500 [THREAD_INFO: ffff8b7e6413c500]

    CPU: 3

    STATE: TASK_INTERRUPTIBLE

    crash> bt

    PID: 1 TASK: ffff8b7e6413c500 CPU: 3 COMMAND: "systemd"

    '#0 [ffffa0f440c6fce0] __schedule at ffffffff9a414ba7

    '#1 [ffffa0f440c6fd80] schedule at ffffffff9a41519c

    '#2 [ffffa0f440c6fd90] schedule_hrtimeout_range_clock at ffffffff9a419691

    '#3 [ffffa0f440c6fe20] schedule_hrtimeout_range at ffffffff9a4196b3

    '#4 [ffffa0f440c6fe30] ep_poll at ffffffff99cf8941

    '#5 [ffffa0f440c6fee0] do_epoll_wait at ffffffff99cf8ae0

    '#6 [ffffa0f440c6ff20] __x64_sys_epoll_wait at ffffffff99cf8b0e

    '#7 [ffffa0f440c6ff30] do_syscall_64 at ffffffff99a0428a

    '#8 [ffffa0f440c6ff50] entry_SYSCALL_64_after_hwframe at ffffffff9a600088

    RIP: 00007ffa791c6bb7 RSP: 00007ffc1c00b9d0 RFLAGS: 00000293

    RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007ffa791c6bb7

    RDX: 00000000000000eb RSI: 00007ffc1c00ba10 RDI: 0000000000000004

    RBP: 00007ffc1c00ba10 R8: 0000000000000000 R9: 7465677261742e79

    R10: 00000000ffffffff R11: 0000000000000293 R12: 00000000000000eb

    R13: 00000000ffffffff R14: 00007ffc1c00ba10 R15: 0000000000000001

    ORIG_RAX: 00000000000000e8 CS: 0033 SS: 002b

    2 切会panic线程

    crash> set -p

    PID: 2613

    COMMAND: "bash"

    TASK: ffff8b7df3cdae00 [THREAD_INFO: ffff8b7df3cdae00]

    CPU: 2

    STATE: TASK_RUNNING (SYSRQ)

    加载module符号表

    1 查看当前加载的module

    crash> mod

    MODULE NAME SIZE OBJECT FILE

    ffffffffc019d0c0 vfio_iommu_type1 24576 (not loaded) [CONFIG_KALLSYMS]

    ffffffffc01a4440 uas 24576 (not loaded) [CONFIG_KALLSYMS]

    ffffffffc01b0b40 rc_core 45056 (not loaded) [CONFIG_KALLSYMS]

    ffffffffc01e76c0 e1000e 249856 (not loaded) [CONFIG_KALLSYMS]

    ffffffffc01fcbc0 usbhid 49152 (not loaded) [CONFIG_KALLSYMS]

    ffffffffc0207580 libahci 32768 (not loaded) [CONFIG_KALLSYMS]

    2 加载所有module符号表

    crash> mod -S

    MODULE NAME SIZE OBJECT FILE

    ffffffffc019d0c0 vfio_iommu_type1 24576 /lib/modules/4.19.53/kernel/drivers/vfio/vfio_iommu_type1.ko

    ffffffffc01a4440 uas 24576 /lib/modules/4.19.53/kernel/drivers/usb/storage/uas.ko

    ffffffffc01b0b40 rc_core 45056 /lib/modules/4.19.53/kernel/drivers/media/rc/rc-core.ko

    ffffffffc01e76c0 e1000e 249856 /lib/modules/4.19.53/kernel/drivers/net/ethernet/intel/e1000e/e1000e.ko

    ffffffffc01fcbc0 usbhid 49152 /lib/modules/4.19.53/kernel/drivers/hid/usbhid/usbhid.ko

    3 加载指定module符号表

    crash> mod -s rc_core /lib/modules/4.19.53/kernel/drivers/media/rc/rc-core.ko

    MODULE NAME SIZE OBJECT FILE

    ffffffffc01b0b40 rc_core 45056 /lib/modules/4.19.53/kernel/drivers/media/rc/rc-core.ko

    crash> mod

    MODULE NAME SIZE OBJECT FILE

    ffffffffc019d0c0 vfio_iommu_type1 24576 (not loaded) [CONFIG_KALLSYMS]

    ffffffffc01a4440 uas 24576 (not loaded) [CONFIG_KALLSYMS]

    ffffffffc01b0b40 rc_core 45056 /lib/modules/4.19.53/kernel/drivers/media/rc/rc-core.ko

    ffffffffc01e76c0 e1000e 249856 (not loaded) [CONFIG_KALLSYMS]

    ffffffffc01fcbc0 usbhid 49152 (not loaded) [CONFIG_KALLSYMS]

    其他命令

    还有很多针对某些内核模块的命令,比如kmem,vm,tree,list,pte等等,参考附件命令列表,后面在使用过程中再学习和研究。

    命令扩展

    crash还支持用户添加在自己的调试命令。可以直接在Crash源码里添加新的命令,更多的是创建一个共享库,用extend动态加载。帮助文档里有一个简单的例子,在crash源码目录下新建一个test.c,把示例代码拷贝进去,就可以进行编译。

    gcc -nostartfiles -shared -rdynamic -o echo.so echo.c -fPIC -D $(TARGET_CFLAGS)

    crash> sys

    KERNEL: ../../kernel-src/linux-4.19.53/vmlinux

    DUMPFILE: 201907070732/dump.201907070732 [PARTIAL DUMP]

    CPUS: 4

    DATE: Sun Jul 7 07:31:34 2019

    UPTIME: 00:10:27

    LOAD AVERAGE: 0.14, 0.16, 0.12

    TASKS: 584

    NODENAME: glbian-OptiPlex-990

    RELEASE: 4.19.53

    VERSION: #1 SMP Sun Jun 23 11:01:25 CST 2019

    MACHINE: x86_64 (3292 Mhz)

    MEMORY: 7.9 GB

    PANIC: "sysrq: SysRq : Trigger a crash"

    可以用sys命令查看机器架构,我的及其machine-type选x86-64,编译命令如下:gcc -shared -rdynamic -o test.so test.c -fPIC -Dx86_64 _D_FILE_OFFSET_BITS=64

    生成test.so。可以用extend直接加载,加载成功后可以看到帮助菜单多了一条echo命令,我们可以基于echo示例开发自己的命令。

    crash> extend ../../src/crash-7.2.6/test.so

    ../../src/crash-7.2.6/test.so: shared object loaded

    crash> extend

    SHARED OBJECT COMMANDS

    ../../src/crash-7.2.6/test.so echo

    crash> help

    ‘* extend mach runq union

    alias files mod search vm

    ascii foreach mount set vtop

    bpf fuser net sig waitq

    bt gdb p struct whatis

    btop help ps swap wr

    dev ipcs pte sym q

    dis irq ptob sys

    echo kmem ptov task

    eval list rd timer

    exit log repeat tree

    结语

    系统崩溃通常是非常棘手的问题,需要非常熟悉内核和相应的子模块,再结合crash工具进行分析,总之需要在实践中累积经验,实践出真知。

    附件

    Crash命令列表

    命令

    功能

    *

    指针快捷健

    alias

    命令快捷键

    ascii

    ASCII码转换和码表

    bpf

    eBPF - extended Berkeley Filter

    bt

    堆栈查看

    btop

    地址页表转换

    dev

    设备数据查询

    dis

    返汇编

    eval

    计算器

    exit

    退出

    extend

    命令扩展

    files

    打开的文件查看

    foreach

    循环查看

    fuser

    文件使用者查看

    gdb

    调用gdb执行命令

    help

    帮助

    ipcs

    查看system V IPC工具

    irq

    查看irq数据

    kmem

    查看Kernel内存

    list

    查看链表

    log

    查看系统消息缓存

    mach

    查看平台信息

    mod

    加载符号表

    mount

    Mount文件系统数据

    net

    网络命令

    p

    查看数据结构

    ps

    查看进程状态信息

    pte

    查看页表

    ptob

    页表地址转换

    ptov

    物理地址虚拟地址转换

    rd

    查看内存

    repeat

    重复执行

    runq

    查看run queue上的线程

    search

    搜索内存

    set

    设置线程环境和Crash内部变量

    sig

    查询线程消息

    struct

    查询结构体

    swap

    查看swap信息

    sym

    符号和虚拟地址转换

    sys

    查看系统信息

    task

    查看task_struct和thread_thread信息

    timer

    查看timer队列

    tree

    查看radix树和rb树

    union

    查看union结构体

    vm

    查看虚拟内存

    vtop

    虚拟地址物理地址转换

    waitq

    查看wait queue上的进程

    whatis

    符号表查询

    wr

    改写内存

    q

    退出

    ad03152a0a53

    图片发自简书App

    展开全文
  • Crash 工具使用

    2021-04-19 10:05:09
    2. crash -m phys_base=0x80000000 vmlinux vmcore crash -m phys_base=0x80000000 --cpus=2 --no_data_debug sysdump vmlinux crash64 -m phys_offset=0x80000000 --no_data_debug sysdump.core symbols/vmlinux ...
    1. cat sysdump.core* > vmcore
    2. crash -m phys_base=0x80000000 vmlinux vmcore
       crash -m phys_base=0x80000000 --cpus=2 --no_data_debug sysdump vmlinux
       crash64 -m phys_offset=0x80000000 --no_data_debug sysdump.core symbols/vmlinux
    3. crash常用命令:  
         1. log 查看log_buf中的内容,sprd即当时内存中保存的kernel log。
         2. ps:查看当前系统进程信息。
         3. p $VAR:打印变量VAR的内容
         4. rd $ADDR $NUM:读取内存地址$ADDR起始的$NUM个内存信息。
    
    4.crash> struct scatterlist -o 查看数据结构定义
    struct scatterlist {
       [0] unsigned long page_link;
       [4] unsigned int offset;
       [8] unsigned int length;
      [12] dma_addr_t dma_address;
    }
    SIZE: 16
    
    5.crash> struct scatterlist 0xd99efd14 -x 查看数据结构值
    struct scatterlist {
      page_link = 3236076226, 
      offset = 3072, 
      length = 512, 
      dma_address = 0
    }
    
    6、sprd_debug_last_regs_access --> cpu最后一次访问寄存器信息保存在这里,在本例子中:
    $ crash> sprd_debug_last_regs_access
    sprd_debug_last_regs_access = $9 = (struct sprd_debug_regs_access *) 0xcf440000
    
    7、知道了last regs的地址,直接查看该变量:
    $ crash> struct sprd_debug_regs_access 0xcf440000 -x //x表示16进制
    struct sprd_debug_regs_access {
      vaddr = 0xf5340004, 
      value = 0x800, 
      stack = 0xc41b3d78, 
      pc = 0xc0391e80, 
      time = 0x1a0bda, 
      status = 0x0
    }
    
    8.当前的runq信息如下:
    crash> runq
    
    9.crash> dis function -x -l 查看函数汇编代码
    
    10.crash> p init_mm
    init_mm = $3 = {
      mmap = 0x0, 
      mm_rb = {
        rb_node = 0x0
      }, 
      mmap_cache = 0x0, 
      get_unmapped_area = 0x0, 
      unmap_area = 0x0, 
      ...
    
    arm-eabi-objdump -h vmlinux
    
    crash> bt -f 1
    PID: 1      TASK: ec0a0000  CPU: 0   COMMAND: "init"
     #0 [<c0619270>] (__schedule) from [<c06198e0>]
        [PC: c0619270  LR: c06198e0  SP: ec09bd98  SIZE: 136]
        ec09bd98: c09065c8 c042db58 00000000 000003ef
        ec09bda8: c06198e0 00ab6000 c02318c4 200f0013
        ec09bdb8: ffffffff c000eda8 ec09a000 bb62cd3f
        ec09bdc8: 0000002c c0980988 c09776c8 c0011b54
        ec09bdd8: c0978808 dd1fcea4 c09065c0 dd1fce40
        ec09bde8: c061ab0c c0011b94 c09065c8 c042db58
        ec09bdf8: dd1fce40 ec09a000 ffffffff ec09a030
        ec09be08: ec84b748 ec0a0000 ec84b74c 00000002
        ec09be18: ec09be2c c06198e0
     #1 [<c06198e0>] (schedule_preempt_disabled) from [<c0618524>]
        [PC: c06198e0  LR: c0618524  SP: ec09be20  SIZE: 16]
        ec09be20: 00000000 ec84b744 0008e634 c0618524
     #2 [<c0618524>] (__mutex_lock_slowpath) from [<c06185d0>]
        [PC: c0618524  LR: c06185d0  SP: ec09be30  SIZE: 48]
        ec09be30: ec84b744 ec84b74c ec84b74c ec0a0000
        ec09be40: ec84b744 dd9576c8 ec84b710 c0a50a30
        ec09be50: c09e1f9c c0a50a30 dd1fce14 c06185d0
     #3 [<c06185d0>] (mutex_lock) from [<c028f71c>]
        [PC: c06185d0  LR: c028f71c  SP: ec09be60  SIZE: 8]
        ec09be60: dd9576d4 c028f71c
     #4 [<c028f71c>] (device_shutdown) from [<c0036528>]
        [PC: c028f71c  LR: c0036528  SP: ec09be68  SIZE: 32]
        ec09be68: ec09be90 c0983554 a1b2c3d4 beb16a07
        ec09be78: fee1dead ec09a000 00000000 c0036528
     #5 [<c0036528>] (kernel_restart) from [<c00366dc>]
        [PC: c0036528  LR: c00366dc  SP: ec09be88  SIZE: 8]
        ec09be88: 00000000 c00366dc
     #6 [<c00366dc>] (sys_reboot) from [<c000f1c0>]
        pc : [<0005b848>]    lr : [<000160cd>]    psr: 200f0010
    

    从sysdump中恢复logcat log:

    crash -m phys_base=0x80000000 --cpus=2 --no_data_debug sysdump vmlinux
    crash> extend <path>/logcat.so
    crash> logcat 
    crash> logcat > logcat.txt

     

    展开全文
  • crash工具分析sysdump

    千次阅读 2018-05-15 21:07:30
    kdump简介 kdump是系统崩溃的时候,用来转储运行内存的一个工具。系统一旦崩溃,内核就没法正常工作了,这个时候将由kdump提供一个用于捕获当前运行信息的内核,该内核会将此时内存中的所有运行状态和数据信息收集...

    kdump简介

     

    kdump是系统崩溃的时候,用来转储运行内存的一个工具。

    系统一旦崩溃,内核就没法正常工作了,这个时候将由kdump提供一个用于捕获当前运行信息的内核,

    该内核会将此时内存中的所有运行状态和数据信息收集到一个dump core文件中以便之后分析崩溃原因。

    一旦内存信息收集完成,可以让系统将自动重启。

     

    kdump是RHEL5之后才支持的,2006被主线接收为内核的一部分。它的原理简单来说是在内存中保留一块

    区域,这块区域用来存放capture kernel,当production kernel发生crash的时候,通过kexec把保留区域的

    capure kernel给运行起来,再由捕获内核负责把产品内核的完整信息 - 包括CPU寄存器、堆栈数据等转储

    到指定位置的文件中。

     

    kdump原理

     

    kexec是kdump机制的关键,包含两部分:

    内核空间的系统调用kexec_load。负责在生产内核启动时将捕获内核加载到指定地址。

    用户空间的工具kexec-tools。将捕获内核的地址传递给生产内核,从而在系统崩溃的时候找到捕获内核的地址并运行。

     

    kdump是一种基于kexec的内核崩溃转储机制。当系统崩溃时,kdump使用kexec启动到第二个内核。第二个内核通常

    叫做捕获内核,以很小内存启动以捕获转储镜像。第一个内核保留了内存的一部分给第二个内核启动使用。

    由于kdump利用kexec启动捕获内核,绕过了BIOS,所以第一个内核的内存得以保留。这是内存崩溃转储的本质。

    捕获内核启动后,会像一般内核一样,去运行为它创建的ramdisk上的init程序。而各种转储机制都可以事先在init中实现。

    为了在生产内核崩溃时能顺利启动捕获内核,捕获内核以及它的ramdisk是事先放到生产内核的内存中的。

    生产内核的内存是通过/proc/vmcore这个文件交给捕获内核的。为了生成它,用户工具在生产内核中分析出内存的使用和

    分布等情况,然后把这些信息综合起来生成一个ELF头文件保存起来。捕获内核被引导时会被同时传递这个ELF文件头的

    地址,通过分析它,捕获内核就可以生成出/proc/vmcore。有了/proc/vmcore这个文件,捕获内核的ramdisk中的脚本就

    可以通过通常的文件读写和网络来实现各种策略了。

     

    kdump配置

     

    RHEL5开始,kexec-tools是默认安装的。

    如果需要调试kdump生成的vmcore文件,需要手动安装kernel-debuginfo包。

     

    (1) 预留内存

    可以修改内核引导参数,为启动捕获内核预留指定内存。

    在/etc/grub.conf (一般为/boot/grub/grub.conf的软链接)中:

    crashkernel=Y@X,Y是为kdump捕获内核保留的内存,X是保留部分内存的起始位置。

    默认为crashkernel=auto,可自行设定如crashkernel=256M。

     

    (2) 配置文件

    配置文件为/etc/kdump.conf,以下是几个常用配置:

     

    # path /var/crash

    默认的vmcore存放目录为/var/crash/%HOST-%DATE/,包括两个文件:vmcore和vmcore-dmesg.txt

     

    # ssh <user@service>

    will copy /proc/vmcore to <user@server>:<path>/%HOST-%DATE/ via SSH

    make sure user has necessary write permissions on server.

    自动拷贝到远程机器上。

     

    # default <reboot | halt | poweroff | shell | mount_root_run_init>

    Actions to perform in case dumping to intended target fails.

    转储失败时执行。

     

    (3) 启动服务

    # chkconfig kdump on // 开机启动

    # service kdump status // start、stop、restart等

     

    (4) 功能验证

    Magic System request key is a magical key combo you can hit which the kernel will respond to regardless

    of whatever else it is doing, unless it is completely locked up.

    使用sysrq需要编译选项CONFIG_MAGIC_SYSRQ的支持。详细信息可看documentation/sysrq.txt。

     

    故意让系统崩溃,来测试kdump是否正常工作。

    # echo c > /proc/sysrq-trigger

    Will perform a system crash by a NULL pointer dereference.

    A crash dump will be taken if configured.

     

    Magic SysRq还有一些很有趣的值,有的具有很大的破环性,输出在/var/log/messages:

    f:call oom_kill to kill a memory hog process. 执行oom killer。

    l:shows a stack backtrace for all active CPUs. 打印出所有CPU的stack backtrace。

    m:dump current memory info. 打印出内存使用信息。

    p:dump the current registers and flags. 打印出所在CPU的寄存器信息。

     

    (5) 捕获内核

    捕获内核是一个未压缩的ELF映像文件,查看捕获内核是否加载到内存中:

    # cat /sys/kernel/kexec_crash_loaded

    缩小捕获内核占用的内存:

    # echo N > /sys/kernel/kexec_crash_size

     

    crash简介

     

    当系统崩溃时,通过kdump可以获得当时的内存转储文件vmcore,但是该如何分析vmcore呢?

    crash是一个用于分析内核转储文件的工具,一般和kdump搭配使用。

    使用crash时,要求调试内核vmlinux在编译时带有-g选项,即带有调试信息。

    如果没有指定vmcore,则默认使用实时系统的内存来分析。

     

    值得一提的是,crash也可以用来分析实时的系统内存,是一个很强大的调试工具。

    crash使用gdb作为内部引擎,语法类似于gdb,命令的使用说明可以用<cmd> help来查看。

    使用crash需要安装crash工具包和内核调试信息包:

    crash

    kernel-debuginfo-common

    kernel-debuginfo

     

    crash使用

     

    Analyze Linux crash dump data or a live system.

    crash [OPTION] NAMELIST MEMORY-IMAGE      (dumpfile form)

    crash [OPTION] [NAMELIST]                                   (live system form)

     

    使用crash来调试vmcore,至少需要两个参数:

    NAMELIST:未压缩的内核映像文件vmlinux,默认位于/usr/lib/debug/lib/modules/$(uname -r)/vmlinux,由

    内核调试信息包提供。

    MEMORY-IMAGE:内存转储文件vmcore,默认位于/var/crash/%HOST-%DATE/vmcore,由kdump生成。

    例如:# crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux   /var/crash/%HOST-%DATE/vmcore

     

    (1) 错误类型

    首先可以在vmcore-dmesg.txt中先查看错误类型,如:

    1. divide error: 0000 [#1] SMP,除数为0造成内核崩溃,由1号CPU触发。

    2. BUG: unable to handle kernel NULL pointer dereference at 000000000000012c,引用空指针。

    这样一来就能知道引发内核崩溃的错误类型。

     

    (2) 错误地点

    RIP为造成内核崩溃的指令,Call Trace为函数调用栈,通过RIP和Call Trace可以确定函数的调用路径,以及在

    哪个函数中的哪条指令引发了错误。

     

    例如RIP为:[<ffffffff812cdb54>] ? tcp_enter_loss+0x1d3/0x23b

    [<ffffffff812cdb54>]是指令在内存中的虚拟地址。

    tcp_enter_loss是函数名(symbol)。

    0x1d3是这条指令相对于tcp_enter_loss入口的偏移,0x23b是函数编译成机器码后的长度。

    这样一来就能确定在哪个函数中引发了错误,以及错误的大概位置。

     

    Call Trace为函数的调用栈,是从下往上看的。可以用来分析函数的调用关系。

     

    (3) crash基本输出

    # crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux   /var/crash/%HOST-%DATE/vmcore

    [plain] view plain copy
    1.  KERNEL: /usr/lib/debug/lib/modules/2.6.32-358.el6.x86_64/vmlinux  
    2. UMPFILE: vmcore  [PARTIAL DUMP]  
    3.    CPUS: 12  
    4.    DATE: Fri Sep 19 16:47:01 2014  
    5.  UPTIME: 7 days, 06:37:46  
    6. AVERAGE: 0.19, 0.05, 0.01  
    7.   TASKS: 282  
    8. ODENAME: localhost.localdomain  
    9. RELEASE: 2.6.32-358.el6.x86_64  
    10. VERSION: #1 SMP Tue Oct 29 10:18:21 CST 2013  
    11. MACHINE: x86_64  (1999 Mhz)  
    12.  MEMORY: 48 GB  
    13.   PANIC: "Oops: 0002 [#1] SMP " (check log for details)  
    14.     PID: 0  
    15. COMMAND: "swapper"  
    16.    TASK: ffffffff81a8d020  (1 of 12)  [THREAD_INFO: ffffffff81a00000]  
    17.     CPU: 0  
    18.   STATE: TASK_RUNNING (PANIC)  

    这些基本输出信息简单明了,可由sys命令触发。

     

    (4) crash常用命令

    bt:打印函数调用栈,displays a task's kernel-stack backtrace,可以指定进程号bt <pid>。

    log:打印系统消息缓冲区,displays the kernel log_buf contents,如log | tail -n 30。

    ps:显示进程的状态,>表示活跃的进程,如ps | grep RU。

    sys:显示系统概况。

    kmem -i:显示内存使用信息。

    dis <addr>:对给定地址进行反汇编。

     

    exception RIP即为造成错误的指令。

    关于log命令:

    内核首先把消息打印到内核态的ring buffer,用户态的klogd负责读取并转发给syslogd,让它记录到磁盘。

    在内核崩溃时,可能无法把消息记录到磁盘,但是ring buffer中一般会有记录。所以log命令有时候能查看

    到系统日志中所缺失的信息。

     

    (5) 结构体和变量

    查看结构体中所有成员的值,例如:

    # ps | grep RU

    [plain] view plain copy
    1. >     0      0   0  ffffffff81a8d020  RU   0.0       0      0  [swapper]  

    # struct task_struct ffffffff81a8d020

    [plain] view plain copy
    1. struct task_struct {  
    2.   state = 0,   
    3.   stack = 0xffffffff81a00000,   
    4.   usage = {  
    5.     counter = 2  
    6.   },   
    7.   flags = 2097408,   

    显示整个结构体的定义:

    # struct task_struct

    [plain] view plain copy
    1. struct task_struct {  
    2.     volatile long int state;  
    3.     void *stack;  
    4.     atomic_t usage;  
    5.     unsigned int flags;  

    显示整个结构体的定义,以及每个成员的偏移:

    # struct -o task_struct

    [plain] view plain copy
    1. struct task_struct {  
    2.      [0] volatile long int state;  
    3.      [8] void *stack;  
    4.     [16] atomic_t usage;  
    5.     [20] unsigned int flags;  
    6.     ...  

    显示结构体中的成员定义,以及它的偏移:

    # struct task_struct.pid

    [plain] view plain copy
    1. struct task_struct {  
    2.   [1192] pid_t pid;  
    3. }  

    显示结构体中成员的值:

    # struct task_struct.pid ffffffff81a8d020

    [plain] view plain copy
    1. pid = 0  

    查看全局变量的值:

    # p sysctl_tcp_rmem

    [plain] view plain copy
    1. sysctl_tcp_rmem = $4 =   
    2.  {40960, 873800, 41943040}  

     

    查看percpu全局变量(加前缀per_cpu_):

    # p per_cpu__irq_stat

    [plain] view plain copy
    1. PER-CPU DATA TYPE:  
    2.   irq_cpustat_t per_cpu__irq_stat; // 变量类型的声明  
    3. PER-CPU ADDRESSES:  
    4.   [0]: ffff880028216540 // 0号CPU对应变量的地址  
    5.   [1]: ffff880645416540  
    6.   ...  

    查看0号CPU对应变量的值:

    # struct irq_cpustat_t ffff880028216540

    [plain] view plain copy
    1. struct irq_cpustat_t {  
    2.   __softirq_pending = 0,   
    3.   __nmi_count = 4780195,   
    4.   irq0_irqs = 148,   
    5.   ...  

     

    (6) 反汇编和源码行

    反汇编:

    # dis ffffffffa021ba91 // 反汇编一条指令

    # dis -l probe_2093+497 10 // 反汇编从某个地址开始的10条指令

    对于内核中的符号:

    # sym tcp_v4_do_rcv // 通过symbol,显示虚拟地址和源码位置

    # sym ffffffff8149f930 // 通过虚拟地址,显示symbol和源码位置

     

    对于模块中的符号:

    需要先加载相应的模块进来,才能显示符号对应的源码:

    # mod // 查看模块

    # mod -s module /path/to/module.ko // 加载模块

    # sym symbol // 显示符号对应的模块源码,也可以用virtual address

     

    (7) 修改内存

    提供动态的修改运行中内核的功能,以供调试,但是RHEL和CentOS上不允许。

    wr:modifies the contents of memory.

    wr [-u | -k | -p] [-8 | -16 | -32 | -64] [address | symbol] value

     

    使用例子:

    # p sysctl_tcp_timestamps

    [plain] view plain copy
    1. sysctl_tcp_timestamps = $3 = 1  

    # wr sysctl_tcp_timestamps 0

    [plain] view plain copy
    1. wr: cannot write to /dev/crash!  


    我勒个擦,/dev/crash的文件属性是rw,但是crash_fops中并没有提供写函数,所以还是只读的。

    这个功能很有用,但被RHEL和CentOS禁止了,所以如需动态修改运行内核还是用systemtap吧。

     

    Reference

     

    [1]. http://www.ibm.com/developerworks/cn/linux/l-cn-kdump1/

    [2]. http://www.ibm.com/developerworks/cn/linux/l-cn-kdump2/

    [3]. http://www.ibm.com/developerworks/cn/linux/l-cn-kdump3/

    [4]. http://www.ibm.com/developerworks/cn/linux/l-cn-kdump4/

    [5]. http://www.ibm.com/developerworks/cn/linux/l-cn-dumpanalyse/

    [6]. http://people.redhat.com/anderson/crash_whitepaper/

    展开全文
  • ramdump crash工具

    千次阅读 2020-04-15 22:43:14
    怎么分析kernel ramdump 1.crash工具安装 首先需要安装一改crash工具,安装包下载链接: http://note.youdao.com/noteshare?id=3253867a92a3315187eb8f1b22703924 解压后,把工具的路径配置到环境变量中:export ...
  • crash工具的使用方法

    2020-11-10 09:39:45
    https://www.jianshu.com/p/ad03152a0a53
  • 《解决Linux内核问题实用技巧之 - Crash工具结合/dev/mem任意修改内存》 Linux内核程序员几乎每天都在和各种问题互相对峙: 内核崩溃了,需要排查原因。 系统参数不合适,需要更改,却没有接口。 改一个...
  • 使用crash工具分析高通ramdump

    千次阅读 2020-04-21 20:43:49
    1.下载并编译arm64平台上的crash工具 从github上下载crash工具源代码: git clone https://github.com/crash-utility/crash.git 编译针对arm64平台的crash工具: make target=ARM64 sudo make install 2.解析高通...
  • 使用 Crash 工具分析 Linux dump 文件

    千次阅读 2018-06-12 09:24:33
    前言Linux 内核(以下简称内核)是一个不与特定进程相关的功能集合,内核的代码很难轻易的在调试器中执行和跟踪。...内核社区和一些商业公司为此开发了很多种调试技术和工具,希望可以让内核的调试...
  • Linux系统用来捕捉kernel dump的产生 vmcore 工具是kdump。vmlinux 文件是 编译过程中产生的。 kdump的原理是启动一个特殊的dump-capture kernel把已经crash的 系统内存里的数据保存到文件里,为什么需要一个特殊的...
  • iOS crash工具

    2019-03-28 12:35:54
    iOS 分析crash工具,一键获取错误信息,位置定位相当精确
  • 本文主要介绍sysdump是什么,以及如何利用工具抓取fulldump,再利用crash工具分析fulldump。 SysDumpSysDump简介如何触发SysDump利用工具抓取FullDumpCrashCrash的安装Crash的使用总结 SysDump SysDump简介 SysDump...
  • Android Crash 工具

    2020-08-27 14:35:47
    本篇文章主要介绍Android开发中的部分知识点,通过阅读本篇文章,您将收获以下内容: 有专业问题或者需要更多干货可以进群找柯南老师 ...k=6W0g8p3E 一、Crash 简介 ...那么Crash就是一个被广泛使用的内核崩
  • 大多数情况下,当我们尝试使用crash工具的wr命令写一个变量或者内存地址的时候,会收获一个报错提示: crash> wr jiffies 123456 wr: cannot write to /proc/kcore 这是因为我们运行的Linux内核...
  • 本文首先介绍了 crash 的基本概念和安装方法,其次详细介绍了如何使用 crash 工具分析内核崩溃转储文件,包括各种常用调试命令的使用方法,最后以几个实际工作中遇到的真实案例向读者展示了 crash 的强大功能。...
  • swift-解析iOScrash工具

    2019-08-15 03:20:39
    Crash分析工具(Tool for analyse iOS Crash
  • 高通crash分析工具

    2018-03-02 10:35:21
    qualcomm平台system dump分析工具,使用方法crash64 vmlinux DDRCS0.BIN@加载地址,DDRCS1.BIN@加载地址 --kaslr auto
  • [Android][Kernel]使用crash工具分析ramdump 前言 本篇只讨论如下内容: 1、crash工具下载、编译 2、crash工具使用需要的文件、数据 3、crash工具使用需要传递的参数 本篇不讨论如下内容: 1、crash分析ram...
  • 本文简介:内核死锁问题一般是读写锁(rw_semaphore)和互斥锁(mutex)引起的,本文主要讲如何通过ramdump+crash工具来分析这类死锁问题。作者简介:朴英敏,现就职于国内一家手机研发公司,任职资深系统工程师,主要...
  • crash 工具使用

    2020-03-22 11:24:10
    crash使用案例 常用命令 dis 反汇编 list 查看链表数据结构,-H 尝尝配合使用,list device_domain_info.global -H device_domain_list struct -o -x 查看结构体成员偏移 task pid 直接查看 task_struct 结构 p ...
  • 玩了一次linux的crash工具。真TMD牛逼.docx
  • crash工具分析linux dump文件

    千次阅读 2014-05-12 14:35:06
    Alicia (Advanced Linux Crash-dump Interactive Analyzer,高级 Linux 崩溃内存转储交互分析器 ) 是一个建立在 lcrash 和 Crash 工具之上的一个内存转储分析工具。它使用 Perl 语言封装了 Lcrash 和 Crash 的底层...
  • 利用crash工具分析堆栈死机问题

    千次阅读 2017-08-20 22:12:51
    将新建共享的crash文件夹挂载到虚拟机,然后使用scp将172.17.171.181:/test/crash/linux-2.6.32-504.16.2.b2.23-debug.tgz文件拷贝到crash目录并解压成功,后面crash使用时会用到你把刚才新建共享的crash文件夹挂载...
  • 使用Crash工具分析 Linux dump文件

    万次阅读 2015-04-13 14:21:20
    前言 Linux 内核(以下简称内核)是一个不与特定进程相关的功能集合,内核的代码很难轻易的在调试器中执行和跟踪。开发者认为,内核如果发生了错误,就不...内核社区和一些商业公司为此开发了很多种调试技术和工具
  • CRASH工具介绍

    千次阅读 2013-07-10 19:29:48
    转自: ...学习 crash命令和其他命令的...crash是和kdump工具配套使用,用于解析kdump生成的vmcore文件。vmcore是内核的映像(实际上是整个内存的映像,一般来说我们会开启过滤功能,只记录内核页)。内核全部的数据结构
  • crash工具命令查询

    2020-11-15 17:29:29
    Crash命令列表 命令 功能 * 指针快捷键 alias 命令快捷键 ascii ASCII转换和码表 bpf 指针快捷键 bt 堆栈查看 btop 地址页表转换 dev 设备数据查询 dis 反汇编 eval 计算器 exit 退出 ...
  • 编写Linux crash工具插件扩展crash命令

    千次阅读 2020-08-14 22:41:42
    我的需求是用crash工具dump出Netfilter的某个hook点所有hook所属模块的名字。 我的方法如下,首先找到模块地址: crash px nf_hooks[2][0] =>var crash list nf_hook_ops.list -s nf_hook_ops.owner -H $var |awk ...
  • crash工具的启动方法

    2020-02-15 12:56:05
    start crash on vmcore sudo rpm -i kernel-default-debuginfo-3.0.101-63.1.x86_64.rpm crash System.map-3.0.101-63-default vmlinux-3.0.101-63-default vmcore 加载mod符号表 ffffffffa057f3a0 xfs ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,767
精华内容 19,106
关键字:

crash工具

友情链接: bys.rar