百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

用trace32分析内核死机

bigegpt 2025-02-11 11:01 8 浏览

dmesg 初步分析

[??423.400073]?Unable?to?handle?kernel?NULL?pointer?dereference?at?virtual?address?00000008
[??423.400075]?[silead?finger_interrupt_handler?505]:S?IRQ?19?,?GPIO?12?state?is?0
[??423.400083]?[silead?finger_interrupt_handler?506]:state?is?0
[??423.400096]?pgd?=?ffffffc0017eb000
[??423.400103]?[00000008]?*pgd=000000008ea0a003,?*pud=000000008ea0a003,?*pmd=000000008ea0b003,?*pte=006000000b000707
[??423.400124]?Internal?error:?Oops:?96000046?[#1]?PREEMPT?SMP
[??423.400132]?Modules?linked?in:?wlan(O)
[??423.400148]?CPU:?4?PID:?0?Comm:?swapper/4?Tainted:?G????????W??O???3.18.31-perf?#1
[??423.400155]?Hardware?name:?Qualcomm?Technologies,?Inc.?MSM8940-PMI8950?MTP?(DT)
[??423.400164]?task:?ffffffc04eae4980?ti:?ffffffc0b28bc000?task.ti:?ffffffc0b28bc000
[??423.400182]?PC?is?at?run_timer_softirq+0x4ac/0x5ec
[??423.400192]?LR?is?at?run_timer_softirq+0x324/0x5ec
[??423.400199]?pc?:?[]?lr?:?[]?pstate:?600001c5
[??423.400204]?sp?:?ffffffc0b28bfb60
...
[??423.401490]?Process?swapper/4?(pid:?0,?stack?limit?=?0xffffffc0b28bc058)
[??423.401496]?Call?trace:
[??423.401510]?[]?run_timer_softirq+0x4ac/0x5ec
[??423.401523]?[]?__do_softirq+0x178/0x350
[??423.401532]?[]?irq_exit+0x74/0xb0
[??423.401543]?[]?__handle_domain_irq+0xb4/0xec
[??423.401553]?[]?gic_handle_irq+0x54/0x84
[??423.401560]?Exception?stack(0xffffffc0b28bfd40?to?0xffffffc0b28bfe60)
...
[??423.401671]?[]?el1_irq+0x68/0xd4
[??423.401685]?[]?cpuidle_enter_state+0xd0/0x224
[??423.401695]?[]?cpuidle_enter+0x18/0x20
[??423.401706]?[]?cpu_startup_entry+0x288/0x384
[??423.401717]?[]?secondary_start_kernel+0x108/0x114
[??423.401728]?Code:?b90052a0?34000840?f9400321?f9400720?(f9000420)?
[??423.401736]?---[?end?trace?d0daa1892c14378b?]---
[??423.401753]?Kernel?panic?-?not?syncing:?Fatal?exception?in?interrupt
[??423.401774]?CPU7:?stopping

连上trace32,load vmlinux后通过list source看下汇编源码混合显示,如下:

  • FFFFFFC0000FE968: 当前汇编指令的虚拟地址
  • F9000760: 汇编机器码,ARM/ARM64的指令机器码都是32位固定长度
  • str x0,[x27, #0x8]: 汇编指令,;后的是注释

根据AAPCS(ARM二进制过程调用标准)参数传递规则,ARM64的 v0 - v7 参数直接由 x0 - x7 传递,其他参数由压栈传递,子程序返回结果保存到x0。

那么这里可推导如下:

x0 == prev, x1 == next

指令:str x0 ,[x1,#0x8]
x1+0x8 其实就是next+8个字节的偏移,看下:

struct?list_head?{
????struct?list_head?*next,?*prev;
};

ARM体系结构中,ARM64一个指针占8个字节内存,也就是: [x1+0x8] == prev

所以这个str指令就是对应上面的next->prev = prev

我们根据异常栈的寄存器值来看下:

[??423.400182]?PC?is?at?run_timer_softirq+0x4ac/0x5ec
[??423.400192]?LR?is?at?run_timer_softirq+0x324/0x5ec
[??423.400199]?pc?:?[]?lr?:?[]?pstate:?600001c5
[??423.400204]?sp?:?ffffffc0b28bfb60
[??423.400210]?x29:?ffffffc0b28bfb60?x28:?ffffffc0b2619038?
[??423.400219]?x27:?ffffffc000c9a000?x26:?0000000000000000?
[??423.400228]?x25:?ffffffc001741120?x24:?ffffffc0006e277c?
[??423.400237]?x23:?ffffffc0b2619000?x22:?ffffffc0b28bfbf8?
[??423.400246]?x21:?ffffffc0b28bc000?x20:?ffffffc0013d2000?
[??423.400254]?x19:?ffffffc0b2618000?x18:?0000007f9588e080?
[??423.400263]?x17:?0000007f9a36d4b4?x16:?ffffffc0001e4f6c?
[??423.400272]?x15:?003b9aca00000000?x14:?0000000000000001?
[??423.400280]?x13:?0000000000000000?x12:?0000000000000001?
[??423.400289]?x11:?000000000000000f?x10:?ffffffc000c9c3f4?
[??423.400297]?x9?:?0000000000000000?x8?:?0000000000000005?
[??423.400305]?x7?:?0000000000000000?x6?:?000000000001451c?
[??423.400314]?x5?:?ffffffc0b2ae8000?x4?:?00135f1aa15bb200?
[??423.400323]?x3?:?0000000000000018?x2?:?0000000000000000?
[??423.400331]?x1?:?0000000000000000?x0?:?ffffffc0b28bfbf8

上面可以看到,x1+0x8 ==0x0000000000000000+0x8==0x0000000000000008,这个和出错时候报的地址一致“Unable to handle kernel NULL pointer dereference at virtual address 00000008”

因为ARM64内核的虚拟地址空间范围是0xFFFF_0000_0000_0000 =>0xFFFF_FFFF_FFFF_FFFF,很明显这个值0x0000000000000008不在范围内,它属于用户空间的虚拟地址空间,肯定会被MMU拦截掉上报data abort异常,所以此题的真正原因是程序跑飞访问非法地址所致。

目前看来从kernel log上的信息无法直接分析出导致问题的具体源代码,从dmesg的这些信息我们已经知道出问题的是这个prev指针,但是比较难直接抓到导致异常的真凶源码位置。

Trace32 分析

利用dmesg我们分析了产生问题时候的来龙去脉,但是想要彻底解决还需要trace32进一步分析。

输入v.f,调出当前的调用栈关系:

可以看到,异常时候的各种参数都显示出来了,这样就非常有利于我们debug了,这也是单纯从dmesg无法得到的重要信息!注意inline类型的函数会被编译器默认优化掉,所以inline类型的函数的参数不可见,需要通过读汇编代码,分析寄存器传参推导。

输入d.list 查看PC停止的位置,如下高亮:

分析Call Stack:

为方便查看,把调用栈信息复制出来,如下:

?1.?...
-007|die(
????|???,
????|????regs?=?0xFFFFFFC0B28BFA40?->?(
????|??????user_regs?=?(regs?=?(0xFFFFFFC0B28BFBF8,?0x0,?0x0,?0x18,?0x00135F1AA15BB200,?0xFFFFFFC0B2AE800
????|??????regs?=?(0xFFFFFFC0B28BFBF8,?0x0,?0x0,?0x18,?0x00135F1AA15BB200,?0xFFFFFFC0B2AE8000,?0x0001451C
????|??????sp?=?0xFFFFFFC0B28BFB60,
????|??????pc?=?0xFFFFFFC0000FEB98,
????|??????pstate?=?0x600001C5,
????|??????orig_x0?=?0xFFFFFFC0B2618000,
????|??????syscallno?=?0xFFFFFFC0000FE7D0),
????|????err?=?0x96000046)
????|??flags?=?0x01C0
????|??ret?=?0x1
????|??tsk?=?0xFFFFFFC04EAE4980
????|??die_counter?=?0x1
-008|__do_kernel_fault.part.5(
????|????mm?=?0x0,
????|????addr?=?0x8,
????|????esr?=?0x96000046,
????|????regs?=?0xFFFFFFC0B28BFA40)
-009|do_page_fault(
????|????addr?=?0x8,
????|????esr?=?0x96000046,
????|????regs?=?0xFFFFFFC0B28BFA40)
????|??tsk?=?0xFFFFFFC04EAE4980
????|??mm?=?0x0
????|??vm_flags?=?0xFFFFFFC000C9A000
????|??vma?=?0xFFFFFFC0B28BFA40
-010|do_translation_fault(
????|????addr?=?0x0A44,
????|????esr?=?0x0124F800,
????|???)
-011|do_mem_abort(
????|????addr?=?0x8,
????|????esr?=?0x96000046,
????|????regs?=?0xFFFFFFC0B28BFA40)
????|??inf?=?0xFFFFFFC0013DC790?->?(
????|????fn?=?0xFFFFFFC000099A74,
????|????sig?=?0x0B,
????|????code?=?0x00030001,
????|????name?=?0xFFFFFFC0010DF250?->?0x6C)
????|??info?=?(
????|????si_signo?=?0x0032D110,
????|????si_errno?=?0xFFFFFFC0,
????|????si_code?=?0x01C0,
????|????_sifields?=?(_pad?=?(0x7,?0x0,?0xB28BF9E0,?0xFFFFFFC0,?0x000A6D78,?0xFFFFFFC0,?0xB28BF9F0,?0xFFF
-012|el1_da(asm)
?-->|exception
-013|__list_del(inline)
-013|detach_timer(inline)
-013|detach_expired_timer(inline)
-013|__run_timers(inline)
-013|run_timer_softirq(
????|???)
????|??base?=?0xFFFFFFC0B2618000?->?(
????|????lock?=?(rlock?=?(raw_lock?=?(owner?=?0x6FCD,?next?=?0x6FCE))),
????|????running_timer?=?0xFFFFFFC001741120?->?(
????|??????entry?=?(next?=?0xFFFFFFC0B27BC9B8,?prev?=?0xFFFFFFC0B27BC9B8),
????|??????expires?=?0x0000000100003098,
????|??????base?=?0xFFFFFFC0B27BC000,
????|??????function?=?0xFFFFFFC0006E277C?->?,
????|??????data?=?0x0,
????|??????slack?=?0xFFFFFFFF,
????|??????start_pid?=?0xFFFFFFFF,
????|??????start_site?=?0x0,
????|??????start_comm?=?(0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0,?0x0))
????|????timer_jiffies?=?0x0000000100003035,
????|????next_timer?=?0x0000000100003034,
????|????active_timers?=?0x7,
????|????all_timers?=?0x7,
????|????cpu_=_0x4,
????|????tv1?=?(vec?=?((next?=?0xFFFFFFC0B2618038,?prev?=?0xFFFFFFC0B2618038),?(next?=?0xFFFFFFC0B2618048
????|????tv2?=?(vec?=?((next?=?0xFFFFFFC0B2619038,?prev?=?0xFFFFFFC0B2619038),?(next?=?0xFFFFFFC0B2619048
????|????tv3?=?(vec?=?((next?=?0xFFFFFFC0B2619438,?prev?=?0xFFFFFFC0B2619438),?(next?=?0xFFFFFFC0B2619448
????|????tv4?=?(vec?=?((next?=?0xFFFFFFC0B2619838,?prev?=?0xFFFFFFC0B2619838),?(next?=?0xFFFFFFC0B2619848
????|????tv5?=?(vec?=?((next?=?0xFFFFFFC0B2619C38,?prev?=?0xFFFFFFC0B2619C38),?(next?=?0xFFFFFFC0B2619C48
????|??fn?=?0xFFFFFFC0006E277C?->
????|??data?=?0x0
????|??it_func_ptr?=?0x0
...

看到这里,我们可以猜想是不是run_timer_softirq的参数出现了问题导致后面发生的一系列异常?可以从这个方向开始思考,我们先来看下这个函数的实现:

static?void?run_timer_softirq(struct?softirq_action?*h)
{
????struct?tvec_base?*base?=?__this_cpu_read(tvec_bases);
????hrtimer_run_pending();
????__run_deferrable_timers();
????if?(time_after_eq(jiffies,?base->timer_jiffies))
????????__run_timers(base);
}

我们看到这个函数最重要的参数变量就是这个base,传入的h没有使用,继续来看下base的结构tvec_base :

struct?tvec_base?{
????spinlock_t?lock;
????struct?timer_list?*running_timer;
????unsigned?long?timer_jiffies;
????unsigned?long?next_timer;
????unsigned?long?active_timers;
????unsigned?long?all_timers;
????int?cpu;??//?跟踪所在的CPU是哪个核,这里是CPU?4
????struct?tvec_root?tv1;
????struct?tvec?tv2;
????struct?tvec?tv3;
????struct?tvec?tv4;
????struct?tvec?tv5;
}?____cacheline_aligned;

这里就看到 tvec_base 的结构里面有个 struct timer_list * 的结构,我们继续看它的结构是怎么样的:

struct?timer_list?{
????/*
?????*?All?fields?that?change?during?normal?runtime?grouped?to?the
?????*?same?cacheline
?????*/
????struct?list_head?entry;
????unsigned?long?expires;
????struct?tvec_base?*base;
????void?(*function)(unsigned?long);
????unsigned?long?data;
????int?slack;
...

首先我们查看 running_timer 的数据内容,

工具栏调出:view -> Watch,输入:(struct timer_list *)0xffffffc001741120

这个就是发生异常的那个timer的数据结构实例,我们最希望的就是希望可以通过这里的数据信息找到它在源码的位置,然后进一步分析它,使用Trace32的 dump 分析功能就可以做到这点。

菜单栏调出:view -> dump

输入地址 0xffffffc001741120 然后点OK

右击高亮,选择view info:

同理,还可以看function的位置(0xFFFFFFC0006E277C):

上面所示,出异常的timer实例就是:fp_drv/m_timer, callback = timer_out_handle,源码位置也给出来了,那么就可以着手修复问题了。

相关推荐

php-fpm的配置和优化

目录概述php-fpm配置php-fpm进程优化配置慢日志查询配置php7进阶到架构师相关阅读概述这是关于php进阶到架构之php7核心技术与实战学习的系列课程:php-fpm的配置和优化学习目标:理...

成功安装 Magento2.4.3最新版教程「技术干货」

外贸独立站设计公司xingbell.com经过多次的反复实验,最新版的magento2.4.3在oneinstack的环境下的详细安装教程如下:一.vps系统:LinuxCentOS7.7.19...

十分钟让你学会LNMP架构负载均衡

业务架构、应用架构、数据架构和技术架构一、几个基本概念1、pv值pv值(pageviews):页面的浏览量概念:一个网站的所有页面,在一天内,被浏览的总次数。(大型网站通常是上千万的级别)2、u...

php从远程URL获取(mp4 mp3)音视频的流媒体数据

/***从远程URL中获取媒体(如mp4mp3)的内容*@parammixed$file_url*@parammixed$media_type...

Zabbix5.0安装部署

全盘展示运行状态,减轻运维人员的重复性工作量,提高系统排错速度,加速运维知识学习积累。1.png1、环境安装关闭SELinux并重启系统2.png安装httpd、mariadb、php运行yum-...

php 常见配置详解

以下是PHP常见的配置项及其含义:error_reporting:设置错误报告级别,可以控制PHP显示哪些错误。例如,设置为E_ALL将显示所有错误,而设置为0将禁止显示任何错误。displa...

实践分享|基于基石智算 DeepSeek API + WordPress 插件自动生成访客回复

基石智算举办的DeepSeek案例大赛汇集了不少基于CoresHubDeepSeekAPI服务或模型部署服务的精彩实践。本次我们将分享个人实践:通过DeepSeekAPI+Word...

如何在Eclipse中搭建Zabbix源码的调试和开发环境

Zabbix是一款非常优秀的企业级软件,被设计用于对数万台服务器、虚拟机和网络设备的数百万个监控项进行实时监控。Zabbix是开放源码和免费的,这就意味着当出现bug时,我们可以很方便地通过调试源码来...

MySQL自我保护参数

#头条创作挑战赛#之前(MySQL自我保护工具--pt-kill)提到用pt-kill工具来kill相关的会话,来达到保护数据库的目的,本文再通过修改数据库参数的方式达到阻断长时间运行的SQL的目...

Python闭包深度解析:掌握数据封装的高级技巧

闭包作为Python高级编程特性之一,为开发者提供了一种优雅的方式来实现数据封装和状态保持。这一概念源于函数式编程理论,在现代Python开发中发挥着重要作用。理解和掌握闭包的使用不仅能够提升代码的表...

Java服务网格故障注入与熔断实战

在分布式系统的高可用性挑战中,服务网格的故障注入与熔断机制是检验系统韧性的终极试金石。以下是10道逐步升级的"地狱关卡",每个关卡都对应真实生产环境中可能遇到的致命场景,并附具体场景示...

MySQL数据库性能优化全攻略:程序员必知的七大核心策略

作为程序员,我们每天都要与数据库打交道。当系统用户量突破百万级时,数据库往往成为性能瓶颈的首要怀疑对象。本文将深入探讨MySQL优化的七大核心策略,并提供可直接落地的优化方案,助您构建高效稳定的数据库...

如何在 Windows 11 上使用单个命令安装 XAMPP

XAMPP是一种广泛使用的软件,用于在Windows操作系统上快速运行LAMP服务器包,包括Windows11。尽管LAMP通常用于Linux系统,但XAMPP并不使用Li...

uTorrent怎样将bt种子转换为磁力

如何用uTorrent把BT种子转为磁力链接?以下方法希望能帮到你。1、在uTorrent窗口里,点击工具栏的按钮,所示。2、在打开窗口里,选取要转为磁力的种子文件,然后点击打开按钮,参照图示操作...

支持向量机SVM 分类和回归的实例

支持向量机(SupportVectorMachine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本、非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合等其他...