-
在当前目录下递归查找so文件中的目标字符串
find . -type f -name "*.so*" -exec sh -c 'strings "$0" | grep "target_string" && echo "$0"' {} \;
这个命令会在当前目录下递归查找所有后缀名为 .so 或者 .so.* 的文件,并使用 strings 命令提取其中的字符串,然后使用 grep 命令在字符串中查找目标字符串,如果目标字符串出现了,就输出包含目标字符串的文件名。 具体来说,该命令使用 find 命令在当前目录下查找所有类型为文件(-type f)且文件名匹配 *.so* 的文件,然后使用 -exec 选项执行后面的命令。 后面的命令使用 sh -c 执行,将每个匹配到的文件名({})传递给了 $0 变量。在命令中,先使用 strings 命令提取文件中的字符串,然后使用 grep 命令查找目标字符串是否存在,如果存在,就使用 echo 命令输出包含目标字符串的文件名。 需要注意的是,命令中使用了单引号包围命令,以避免 Shell 解析命令中的 $0 变量和 {} 字符。同时,在命令的末尾需要使用 \; 来表示命令的结束,而不是使用分号 ;,因为分号 ; 是 Shell 的保留字符。
-
objdump 反汇编代码带行号:
objdump -d -l -S your_binary_file
这个命令中的参数含义如下:
-d:表示进行反汇编。
-l:表示生成包含行号信息的输出。
-S:表示同时输出源代码。
-C:如果二进制文件包含 C++ 符号,使用 C++ 符号名进行显示,而不是使用原始符号名。
将 your_binary_file 替换为你要反汇编的二进制文件的路径。
这将生成一个包含反汇编代码和源代码行号信息的输出。你可以查看这个输出来分析程序的汇编代码。
- 注意事项:cmake-objdump
- cmake中使用参数-DCMAKE_BUILD_TYPE=Release编译出来的版本在coredump时生成的dmesg报错中的ip地址与使用-DCMAKE_BUILD_TYPE=Debug编出来的版本再使用objdump反汇编得到的汇编代码对不上。
- cmkke中-DCMAKE_BUILD_TYPE=Release编译出来的版本在coredump时生成的dmesg报错中的ip地址与在CMakeLists.txt中额外添加set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")编译选项后再使用objdump反汇编得到的汇编代码对应的上。
- cmake中-DCMAKE_BUILD_TYPE=Debug编译出来的版本后用strip得到的不含调试包的版本在coredump时生成的dmesg报错中的ip地址与使用-DCMAKE_BUILD_TYPE=Debug编出来的版本再使用objdump反汇编得到的汇编代码对应的上。
- 注意事项:cmake-objdump
查看某个结构体或变量的类型定义:
ptype filep查看某个结构体或变量的类型定义且包含偏移量信息:
ptype /o struct file-
(gdb) disassemble /m main
-
https://sourceware.org/gdb/current/onlinedocs/gdb/Source-Path.html#index-set-substitute_002dpath
-
替换查找源文件的目录 set substitute-path from-path to-path
cd lshw-02.18.85.3 gdb lshw b main gef➤ l 75 in lshw.cc gef➤ info source Current source file is lshw.cc Compilation directory is /build/lshw-02.18.85.3/src Located in /build/lshw-02.18.85.3/src/lshw.cc Source language is c++. Producer is GNU C++14 8.3.0 -mtune=generic -march=x86-64 -g -O2. Compiled with DWARF 2 debugging format. Does not include preprocessor macro info. gef➤ set substitute-path /build/lshw-02.18.85.3/src ./src gef➤ l warning: Source file is more recent than executable. 75 int main(int argc, 76 char **argv) 77 { 78 79 #ifndef NONLS 80 setlocale (LC_ALL, ""); 81 bindtextdomain (PACKAGE, LOCALEDIR); 82 bind_textdomain_codeset (PACKAGE, "UTF-8"); 83 textdomain (PACKAGE); 84 #endif
- errno全局变量及使用细则,C语言errno全局变量完全攻略
- Linux(程序设计):08-perror、strerror函数(errno全局变量)
- Linux errno 错误对照表
- 【博客272】errno错误对照表
- gcc 7.1.0下gdb无法prinf查看errno解决
- 40.Linux应用调试-使用gdb和gdbserver
- 使用gdbserver远程调试
- 服务/软件管理:38-gdb+gdbserver的使用
- gdb远程及本地调试的一些技巧
- 使用GDB进行嵌入式远程调试
- 调试 Linux 最早期的代码
- https://github.com/yuan-xy/Linux-0.11
- Linux 0.11 vscode + gdb调试环境搭建
- 利用vscode远程调试Linux内核
-
Linux下常用的串口助手 —— minicom、putty、cutecom
主机上执行:
sudo minicom -s -D /dev/ttyUSB0
ls -l /dev/ttyUSB0找不到设备时可以尝试手动添加:lsusb
echo '067b 23a3' > /sys/bus/usb-serial/drivers/generic/new_id
被调式机上执行:
sudo cutecom
-
查询串口波特率:
stty -F /dev/ttyS0
其中 /dev/ttyS0 是串口设备文件的路径。你可以将路径更改为你所关心的特定串口。
这将返回串口的配置,包括波特率、数据位、校验位、停止位等。通常,波特率会显示在配置输出中,如下所示:
speed 9600 baud; line = 0; -
设置串口波特率
stty -F /dev/ttyS0 9600
在上面的命令中:
/dev/ttyS0 是串口设备文件的路径,你可以根据需要更改为你使用的串口。
9600 是所需的波特率。你可以将其替换为你想要的任何波特率。
运行此命令后,串口 /dev/ttyS0 的波特率将设置为 9600。确保串口没有被其他程序占用,以便成功设置波特率。
- Linux GDB的实现原理
- 一文带你看透 GDB 的 实现原理 ptrace真香
- 断点原理与实现
- 硬件断点和软件断点的区别
- ROM, FLASH和RAM的区别
- 调试器工作原理CPU软件断点/硬件断点/单步执行标识
- 硬件断点
- 内存断点
- 软件断点
- Linux ptrace系统调用详解:利用 ptrace 设置硬件断点
- watch 命令实现监控机制的方式有 2 种,一种是为目标变量(表达式)设置硬件观察点,另一种是为目标变量(表达式)设置软件观察点。
- Linux内核:自己动手写一个GDB设置断点(原理篇)
-
core[1161856]: segfault at 0 ip 0000000000401136 sp 00007ffcdbaf3240 error 6 in core[401000+1000] likely on CPU 2 (core 2, socket 0)
-
core[1161856]: 这可能是指示生成的 core dump 文件名。在这里,core 文件名为 "core",后缀为 "1161856",这可能是一个进程 ID 或其他唯一标识符。
-
segfault at 0: 这表示一个段错误(Segmentation Fault)发生在地址 0 处。这通常是因为程序试图访问一个无效的内存地址。
-
ip 0000000000401136: 这是导致段错误的指令的地址。在这里,ip(Instruction Pointer)指向地址 0000000000401136 的指令。
-
sp 00007ffcdbaf3240: 这是栈指针(Stack Pointer),指向栈的当前顶部。在这里,sp 指向地址 00007ffcdbaf3240。
-
error 6: 这是一个错误代码,表示导致段错误的原因。在 Linux 中,错误代码 6 通常表示尝试执行非法的指令。
-
core[401000+1000]: 这表示 core dump 文件的内存范围。在这里,core 文件捕获了从地址 401000 开始的 1000 个字节的内存内容,1000一般指向了_init符号。
-
likely on CPU 2 (core 2, socket 0): 这是指示错误可能发生在第二个 CPU 核心上,该核心位于第一个物理 CPU 插槽上。
-
- coredumpctl - Retrieve and process saved core dumps and metadata
- 使用systemd的coredump工具分析程序崩溃问题
- 18 使用 systemd-coredump 针对应用程序崩溃进行调试
- [linux][异常检测] hung task, soft lockup, hard lockup, workqueue stall
- Softlockup与hardlockup检测机制(又名:nmi_watchdog)
- 一起学习64位ARM平台稳定性分析:遇见内核 panic
- Linux内核故障分类和排查
- 这是你了解的空指针吗?
- Linux内核panic核心执行逻辑
更改 sysctl 中的某些内核参数可能导致系统不稳定,甚至触发 panic。以下是一些可能会导致系统问题的内核参数,慎重修改:
-
kernel.panic
作用: 设置系统 panic 的延迟时间。
潜在风险: 如果将其设置得太低,系统可能会在不必要的情况下触发 panic。
sysctl -w kernel.panic=10
内核编译选项:CONFIG_PANIC_TIMEOUT=0
-
kernel.panic_on_oops
作用: 控制在发生内核 oops(可修复的内核错误)时是否触发 panic。
潜在风险: 如果启用,系统在 oops 时会触发 panic。
sysctl -w kernel.panic_on_oops=1
内核编译选项:PANIC_ON_OOPS=y
-
kernel.hung_task_panic
作用: 控制在系统检测到“挂起”任务(可能是由于死锁)时是否触发 panic。
潜在风险: 如果启用,系统在检测到挂起任务时会触发 panic。
sysctl -w kernel.hung_task_panic=1
内核编译选项:CONFIG_DETECT_HUNG_TASK=y CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
-
kernel.hung_task_timeout_secs:
作用: 该参数用于设置系统在检测到任务挂起(hanging task)的超时时间。如果系统中的某个任务在指定的时间内没有恢复正常运行,内核将记录信息并采取相应的措施。
默认值: 通常情况下,kernel.hung_task_timeout_secs 的默认值是 120 秒(2 分钟)。
潜在风险: 如果将其设置得太低,系统可能会对一些正常但需要一定时间来完成的任务误报为挂起状态。
sysctl -w kernel.hung_task_timeout_secs=60
内核编译选项:CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
-
vm.panic_on_oom
作用: 控制在发生内存耗尽(OOM)时是否触发 panic。
潜在风险: 如果启用,系统在内存不足时会触发 panic。
sysctl -w vm.panic_on_oom=1
-
kernel.softlockup_panic
作用: 软死锁是指内核中的一个任务(线程)由于长时间未能释放CPU而导致系统失去响应时是否触发 panic。
潜在风险: 如果启用,系统在检测到软锁定时会触发 panic。
sysctl -w kernel.softlockup_panic=1
内核编译选项:CONFIG_SOFTLOCKUP_DETECTOR=y BOOTPARAM_SOFTLOCKUP_PANIC=y
-
kernel.panic_on_warn
作用: 这个参数控制内核在遇到某些非致命性错误(例如警告)时是否触发 panic。
0: 禁用自动重启。内核在遇到警告时不会触发系统重启,而是继续正常运行。
1: 启用自动重启。当内核发生某些警告时,系统会自动重启。
sysctl -w kernel.panic_on_warn=1
在调试或特殊情况下,禁用自动重启可能有助于保留内核警告的信息以进行故障排除。在生产环境中,通常将其设置为非0,以确保系统在遇到某些严重问题时能够自动重启,尽早恢复正常运行状态。
sysctl -w kernel.hung_task_panic=1、echo 1 > /proc/sys/kernel/hung_task_panic这两种方法都是在运行时直接生效的,而且都是暂时性的修改。
如果你希望修改是持久的,可以将相应的配置写入 /etc/sysctl.conf 文件,并使用 sysctl -p 命令使其生效。
sudo cat << EOF >> /etc/sysctl.conf
# sysrq
# CONFIG_MAGIC_SYSRQ=y
kernel.sysrq=1
# panic
# CONFIG_PANIC_TIMEOUT=0
kernel.panic=10
# CONFIG_PANIC_ON_OOPS=y
kernel.panic_on_oops=1
# CONFIG_DETECT_HUNG_TASK=y CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
kernel.hung_task_panic=1
# CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
kernel.hung_task_timeout_secs=60
vm.panic_on_oom=1
# CONFIG_SOFTLOCKUP_DETECTOR=y BOOTPARAM_SOFTLOCKUP_PANIC=y
kernel.softlockup_panic=1
kernel.panic_on_warn=1
EOFsysctl -p任务挂起(hanging task)和睡眠(sleep)是两个概念,涉及到系统中运行的进程和线程的状态。
任务挂起(Hanging Task):
-
定义: 任务挂起指的是系统中的某个任务(通常是一个进程或线程)由于某种原因而无法继续正常执行,长时间处于一种不响应的状态。
-
原因: 挂起可能是由于死锁、资源争用、错误的程序行为或其他系统问题引起的。
-
检测: 内核通过监视任务的执行状态和超时机制来检测是否有任务挂起。
-
处理: 一旦检测到任务挂起,系统可能会采取相应的措施,例如记录相关信息、触发系统 panic,以及尝试恢复任务的正常执行。
睡眠(Sleep):
-
定义: 睡眠指的是一个任务主动放弃 CPU 并进入一种等待状态,等待某个事件的发生。在睡眠期间,任务通常不占用 CPU 时间,并允许其他任务执行。
-
原因: 任务可能进入睡眠状态以等待外部事件,例如等待 I/O 操作完成、等待定时器触发、等待信号量或锁的释放等。
-
检测: 睡眠通常是由任务自己通过系统调用(如 sleep、wait)或内核操作引起的,不同于挂起的 passivity(被动性)。
-
处理: 睡眠是一种正常的任务状态,系统不会像在检测到挂起时那样采取紧急措施。任务会在等待的事件发生时被唤醒,继续执行。
总的来说,任务挂起通常是一种异常状态,可能导致系统不稳定,而睡眠是一种正常的、被控制的状态,允许任务在需要时主动放弃 CPU 并等待特定条件的发生。
-
nmi_watchdog= [KNL,BUGS=X86] Debugging features for SMP kernels Format: [panic,][nopanic,][num] Valid num: 0 or 1 0 - turn hardlockup detector in nmi_watchdog off 1 - turn hardlockup detector in nmi_watchdog on When panic is specified, panic when an NMI watchdog timeout occurs (or 'nopanic' to not panic on an NMI watchdog, if CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is set) To disable both hard and soft lockup detectors, please see 'nowatchdog'. This is useful when you use a panic=... timeout and need the box quickly up again. These settings can be accessed at runtime via the nmi_watchdog and hardlockup_panic sysctls.
-
Documentation for Kdump - The kexec-based Crash Dumping Solution
-
sudo apt install kdump-tools crash kexec-tools makedumpfile linux-image-$(uname -r)-dbguname -a Linux wujing-PC 5.15.77-amd64-desktop #2 SMP Thu Jun 15 16:06:18 CST 2023 x86_64 GNU/Linux cat /etc/default/grub.d/kdump-tools.cfg GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT crashkernel=384M-:128M"
uname -a Linux wujing-PC 4.19.0-arm64-desktop-tyy-5312 #5312 SMP Tue Dec 12 10:52:22 CST 2023 aarch64 GNU/Linux cat /etc/default/grub.d/kdump-tools.cfg GRUB_CMDLINE_LINUX_DEFAULT="$GRUB_CMDLINE_LINUX_DEFAULT crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M"
echo 1 > /proc/sys/kernel/sysrq echo c > /proc/sysrq-trigger
-
修改sysconfig kdump参数,禁用某些驱动:
vim /etc/sysconfig/kdump KDUMP_COMMANDLINE_APPEND="initcall_blacklist=mlx5_ib_init,mlx5_core_init module_blacklist=mlx5_ib,mlx5_core modprobe.blacklist=hisi_sas_v3_hw,hisi_sas_main"systemctl restart kdump.service
crash 是一个用于分析 Linux 内核转储文件(core dump)的工具,允许在不中断系统运行的情况下进行诊断。以下是 crash 的一些基本原理:
-
核心文件: crash 的核心原理是基于核心文件的分析。内核转储文件(core dump)记录了系统在发生关键错误时的内存和寄存器状态。crash 使用这些核心文件进行分析。
-
调试信息: 为了正确解析核心文件,crash 需要访问内核二进制文件(通常是 vmlinux)。这个文件包含有关内核符号、数据结构和函数的调试信息。在使用 crash 之前,你需要确保有匹配正在运行内核的 vmlinux 文件。
-
在线调试: crash 允许在线调试运行中的内核,而无需停止系统。它通过访问 /proc/kcore 文件获取正在运行内核的内存映像,结合核心文件和调试信息,提供了对内核状态的深入分析。
-
命令式界面: crash 提供了一个交互式的命令行界面,用户可以在其中运行各种命令以查看内核状态、进程信息、调度器信息等。这样用户可以动态地检查系统状态。
-
插件系统: crash 具有可扩展的插件系统,可以通过插件添加额外的命令和功能。这使得用户可以根据需要定制分析环境。
-
安全性和谨慎使用: 尽管 crash 在不中断系统的情况下进行诊断,但仍需注意,对于生产环境,谨慎使用是很重要的。某些 crash 命令可能会对系统产生影响,因此建议在测试环境中使用。
总的来说,crash 提供了一种非常强大的工具,用于在不影响系统运行的情况下进行 Linux 内核的调试和分析。
git clone https://github.com/crash-utility/crash.git
cd crash/
git checkout -b 8.0.4 8.0.4
make -j16
sudo make install- 【调试】crash使用方法
- Linux crash 调试环境搭建
- linux内核学习-Linux内核程序调试工具Crash的安装
- dump分析工具_ubantu18.04内核奔溃调试工具Crash的搭建
- 用crash tool观察ARM64 Linux地址转换
- CRASH安装和调试
- Linux crash Dump分析
仅为一个命令启用存储库:
sudo dnf --enablerepo=fedora-debuginfo,updates-debuginfo install kernel-debuginfo永久启用存储库(可能不是您想要的):
sudo dnf config-manager --set-enabled fedora-debuginfo updates-debuginfo禁用存储库:
sudo dnf config-manager --set-disabled fedora-debuginfo updates-debuginfo推荐使用sudo dnf debuginfo-install kernel安装内核调试包:
sudo dnf debuginfo-install kernel有时我们想知道一个数字的那些位是1,那么需要在数字前面使用-b参数:
crash> cpumask 0xffff88b48aa23f20 -x
struct cpumask {
bits = {0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x90004000, 0x0, 0x1, 0xffffc9000d20c000, 0x420804000000002, 0x0, 0x0, 0x3700000000, 0x4, 0xfffb706a, 0xffff88ea8be9c000, 0x3700000037, 0x7800000000, 0x7800000078, 0x0, 0xffffffff82260540, 0x100000, 0x400000, 0x100000, 0x1, 0x0, 0x0, 0xffff88b48aa240b0, 0xffff88b48aa240b0, 0x0, 0xd4da92e6, 0x26554, 0xffffffffff3b4a54, 0x1fe63, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff88b492fe9a00, 0x0, 0x0, 0x0, 0x0, 0xd4da9000, 0x1a, 0x1a, 0x2a400006be6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffff88b48aa24280, 0xffff88b48aa24280, 0x0, 0x0, 0x64, 0x0, 0x0, 0xffff88b492fe9bc0, 0x0, 0xffffffff83149580, 0xffff88b48aa242d0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
}
crash> eval -b 0x3 //vcpu0的SMT调度域包含vcpu0和vcpu1一对超线程
bits set: 1 0
crash># include/linux/swait.h
# 知道swait_queue_head地址,crash中怎么用list命令得到第62行的task地址
crash> p &(rcu_sched_state.gp_wq)
$96 = (struct swait_queue_head *) 0xffff3eb87f2132d8
crash> list -o swait_queue.task_list -s task_struct.pid,comm -O swait_queue_head.task_list -h 0xffff3eb87f2132d8
list: invalid option -- 'O'
Usage:
list [[-o] offset][-e end][-[s|S] struct[.member[,member] [-l offset]] -[x|d]]
[-r|-B] [-h|-H] start
Enter "help list" for details.[root@obs-arm-worker-01 127.0.0.1-2025-05-11-23:11:38]# crash --version
crash 7.2.8-5.ctl2crash版本太低,改用-o选项:
crash> p &(rcu_sched_state.gp_wq.task_list)
$98 = (struct list_head *) 0xffff3eb87f2132e0
crash> list -o swait_queue.task -s task_struct.pid,comm -H 0xffff3eb87f2132e0
(empty)查看内存的使用统计信息:
kmem -i查看slab的信息:
kmem -s > kmem_s.log按slabs降序:
cat kmem_s.log | sort -k5,5nr | head -n10
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
ffff8003ff689900 304 3563564 7039393 282756 16k kmemleak_object
ffff8003ad115800 192 1597195 1601956 51676 16k dentry(664:aTrustDaemon.service)
ffff80037d372700 1072 409123 409620 17826 32k ext4_inode_cache(904:session-1.scope)
ffff80037d375800 192 307034 310121 10007 16k dentry(904:session-1.scope)
ffff8003e87c8b00 128 332086 332185 9491 16k kernfs_node_cache
ffff80037d375480 144 147286 172328 5213 16k buffer_head(904:session-1.scope)
ffff8003ff688400 128 86102 86450 3458 16k kmalloc-128
ffff80037d375b80 192 63328 63365 2051 16k vm_area_struct(904:session-1.scope)
ffff80037d374680 64 37358 37400 1873 8k anon_vma_chain(904:session-1.scope)
ffff8003954a1580 40 34932 34944 1664 8k ext4_extent_statuscrash> kmem -o
PER-CPU OFFSET VALUES:
CPU 0: ffff88807f600000
CPU 1: ffff88807fa00000
CPU 2: ffff88813d600000
CPU 3: ffff88813da00000
CPU 4: ffff8881bd600000
CPU 5: ffff8881bda00000
CPU 6: ffff88823d600000
CPU 7: ffff88823da00000以下面这个全局percpu变量call_single_queue为例:
static DEFINE_PER_CPU_SHARED_ALIGNED(struct llist_head, call_single_queue);crash> p call_single_queue
PER-CPU DATA TYPE:
struct llist_head call_single_queue;
PER-CPU ADDRESSES:
[0]: ffff88807f800340
[1]: ffff88807fc00340
[2]: ffff88813d800340
[3]: ffff88813dc00340
[4]: ffff8881bd800340
[5]: ffff8881bdc00340
[6]: ffff88823d800340
[7]: ffff88823dc00340查看其在某些CPU上的具体内容:
crash> p call_single_queue:0,2,5-7
per_cpu(call_single_queue, 0) = $5 = {
first = 0x0
}
per_cpu(call_single_queue, 2) = $6 = {
first = 0x0
}
per_cpu(call_single_queue, 5) = $7 = {
first = 0x0
}
per_cpu(call_single_queue, 6) = $8 = {
first = 0x0
}
per_cpu(call_single_queue, 7) = $9 = {
first = 0x0
}struct kmem_cache {
struct array_cache __percpu *cpu_cache;
/* 1) Cache tunables. Protected by slab_mutex */
unsigned int batchcount;
unsigned int limit;
unsigned int shared;
...以16进制方式查看 kmem_cache 的 per-CPU 缓存指针(cpu_slab)的偏移量:
crash> struct kmem_cache.cpu_slab -x ffff893751f60800
cpu_slab = 0x5fc135c77b40,上面cpu_slab的偏移量是0x5fc135c77b40
假如想知道这个成员在cpu10上的地址,下面有2种方法:
-
绝对值相加
首先获取percpu变量在cpu10上的基地址:
crash> kmem -o | grep "CPU 10" CPU 10: ffff88debfd00000
然后相加即可:
crash> eval ffff88debfd00000 + 0x5fc135c77b40 hexadecimal: ffffe89ff5977b40 decimal: 18446718372450630464 (-25701258921152) octal: 1777777211776545675500 binary: 1111111111111111111010001001111111110101100101110111101101000000
上面将相加后的结果分别按16进制,10进制,8进制以及2进制进行了输出。
-
使用ptov
crash> ptov 0x5fc135c77b40:10 PER-CPU OFFSET: 5fc135c77b40 CPU VIRTUAL [10] ffffe89ff5977b40这种方法更加方便。
还是以kmem_cache为例:
crash> struct kmem_cache.cpu_slab -x ffff893751f60800
cpu_slab = 0x5fc135c77b40,如果想读取cpu_slab的内容,之前的办法是先得到绝对地址,然后再读取(用*代替struct),其实也可以直接读取,下面的例子读取cpu2上的cpu_slab的内容:
crash> *kmem_cache_cpu 0x5fc135c77b40:2
[2]: ffffe89ff5577b40
struct kmem_cache_cpu {
freelist = 0x0,
tid = 2,
page = 0x0,
partial = 0x0
}使能魔法键c:
echo 1 > /proc/sys/kernel/sysrq魔法键c主动生成kdump:
echo c > /proc/sysrq-trigger等价于echo c > /proc/sysrq-trigger:
Alt+PrtSc+C- 手动触发kdump,触发后服务器会自动重启。(正常情况下勿按该组合键)
IPMI可通过发送NMI(Non-Maskable Interrupt)强制触发内核崩溃,进而生成vmcore:
ipmitool -I lanplus -H {ipmi lan IP address} -U {username} -P {passwd} chassis power diag
