当前位置: 首页 > news >正文

深入解析:Linux x86 stability和coredump

深入解析:Linux x86 stability和coredump

1 POSIX pthread_create原理
1)fork()、pthread_create()、vfork()对应的系统调用分别是sys_fork()、sys_clone()、sys_vfork(),它们在内核中都是经过do_fork()实现的。
2)系统中所有的进程都组织在init_task.tasks链表下面,每个进程的线程组织在每个进程task_sturct->signal的链表下。参考函数for_each_process()和for_each_process_thread()。
3)根据上述分析,Linux用户态和内核线程都由task_struct结构体描述,是一个轻量级的进程,因此内核中current变量可以表示进程、用户态线程和内核线程。

2 kernel的log机制
2.1 kernel代码中调整loglevel
int old_lvl = console_loglevel;
console_loglevel = CONSOLE_LOGLEVEL_MOTORMOUTH;
// TODO
console_loglevel = old_lvl;

2.2 Linux Kernel动态log
- 需在内核中部署CONFIG_DYNAMIC_DEBUG,并且将debugfs挂载到某个文件夹mount -t debugfs none /sys/kernel/debug/
- 通过echo -n "file xxxxxx.c +p" > /sys/kernel/debug/dynamic_debug/control(或者/d/dynamic_debug/control)来打开调试信息

2.3 Kernel hexdump
print_hex_dump(KERN_INFO, "",
DUMP_PREFIX_OFFSET, 16, 1,
buf,
len,
true);

3 Interrupt
3.1 中断上半部
arch/x86/kernel/irq.c
do_IRQ()
分析do_IRQ()函数可知,Linux内核在x86平台上不支撑中断嵌套。

3.2 中断下半部
tasklet基于softirq。

3.3 irqbalance
https://github.com/ix5/android-irqbalance

4 x86 NMI watchdog
4.1 工作原理
soft lockup:禁止抢占,使用了spin_lock()
hard lockup:禁止抢占和禁止CPU local irq,应用了spin_lock_irqsave()
用户态watchdog:/dev/watchdog

kernel/watchdog.c
hrtimer的处理函数:watchdog_timer_fn
调用wake_up_process函数唤醒此cpu上的watchdog线程,如果watchdog线程被唤醒就会去刷新时间戳。倘若系统关了抢占,此watchdog线程不会被唤醒,这样时间戳就不会更新。

4.2 soft lockup
Soft Lockup refers to the occurrence of the CPU that has occurred in 20 seconds (default) does not have scheduling switching.
Refer to Analysis of soft lockup mechanism of Linux series AND Using RCU’s CPU Stall Detector.

echo 30 > /proc/sys/kernel/watchdog_thresh

4.3 watchdog线程调度方式
- kernel/watchdog.c
- SCHED_FIFO,最高优先级MAX_RT_PRIO - 1 = 99
- 实时进程的优先级(rt_priority)数字越大则优先级越高,99最高,0最低;而普通进程正好相反,优先级(prio)数字越大则优先级越低,100最高,139最低(对应nice值-20 ~ 19)
- 内核调度是按照task_struct中的prio来调度的,所以内核会将实时线程的rt_priority转换成prio:prio = MAX_RT_PRIO - 1 - p->rt_priority;prio的值越小,优先级就越高

4.4 进程的调度方式和优先级
ps -Al
chrt -p $PID

4.5 per-CPU变量
current,每个CPU一个变量:
arch/x86/include/asm/current.h
DECLARE_PER_CPU(struct task_struct *, current_task);

抢占计数,每个CPU一个变量:
arch/x86/include/asm/preempt.h
DECLARE_PER_CPU(int, __preempt_count);
CPUx的抢占禁止了后,实际上就是一个单片机,只能执行关闭抢占的线程以及响应硬件的中断。

4.6 kmod demo
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/kthread.h>

static struct task_struct *task0;
static spinlock_t spinlock;
static int val;

int task(void *arg)
{
printk(KERN_INFO "%s:%d\n",
__func__, __LINE__);
/* To generate panic uncomment following */
/* panic("softlockup: hung tasks"); */

while (!kthread_should_stop()) {
printk(KERN_INFO "%s:%d\n",
__func__, __LINE__);
spin_lock(&spinlock);
/* busy loop in critical section */
while(1) {
// printk(KERN_INFO "%s:%d\n",
__func__, __LINE__);
}
spin_unlock(&spinlock);
}
return val;
}

static int softlockup_init(void)
{
printk(KERN_INFO "%s:%d\n",
__func__, __LINE__);

val = 1;
spin_lock_init(&spinlock);
task0 = kthread_run(&task, (void *)val,
"softlockup_thread");
set_cpus_allowed_ptr(task0, cpumask_of(0));
return 0;
}

static void softlockup_exit(void)
{
printk(KERN_INFO "%s:%d\n",
__func__, __LINE__);
kthread_stop(task0);
}

module_init(softlockup_init);
module_exit(softlockup_exit);
MODULE_LICENSE("GPL");

4.7 lockdep
lockdep:lock dependency
CONFIG_PROVE_LOCKING=y
打开lockdep时内核启动后会自动配置console loglevel到CONSOLE_LOGLEVEL_MOTORMOUTH(=15),可以修改代码将这个配置屏蔽,不然打印的内核log太多。

5 addr2line和objdump启用
5.1 带有完整调试信息的符号路径
./out/target/product/[PROJECT]/symbols/vendor/lib64/

5.2 addr2line
addr2line -C -f -e libxxx.so <地址>
其中地址为#00 Frame前面显示的pc指向的地址

aarch64-linux-android-addr2line -C -f -e vmlinux <目标地址>

5.3 objdump
objdump -l -C -S libxxx.so > deasm.log
vi deasm.log
输入#00 Frame前面显示的pc指向的地址(需要去掉前面的多个0)

5.4 gdb vmlinux
Use 7-Zip to extract vmlinux from IPK file. The following l means list.
gdb vmlinux
l *func_name+offset_addr

6 coredump
通过Aarch64 Linux SDK中能够运行xxx-gdb来调试core dump。

Default core dump, must use sudo bash -c 'shell command' to run coredump configuration.
sudo bash -c 'echo "/data/core.%e.%p" > \
/proc/sys/kernel/core_pattern'
ulimit -c <size>: unit is block (= 512bytes)
ulimit -c unlimited
gdb main core.main.19188

7 Abbreviations
为了代替SMBus就是HECI:Host Embedded Controller Interface,Host OS和x86 ME的通信接口,只有4pin,分别是REQ#、GNT#、TX和RX,目的

http://www.wxhsa.cn/company.asp?id=4917

相关文章:

  • 9.15更新linux命令
  • Jenkins 容器和 Kubernetes Agent
  • LGP7916 [CSP-S 2021] 交通规划 学习笔记
  • 详细介绍:【Kubernetes】常见面试题汇总(十四)
  • 萤火虫文旅年票、为何能成为撬动万亿文旅市场的利器
  • 教育行业API安全最佳实践:全知科技以国家标准引领数据防护新范式
  • Codecademy Pro是否值得?2023年深度评测与技术特性解析
  • Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
  • 实用指南:【性能优化需要关注的参数——Batches】
  • 禁止指定软件联网
  • 详细介绍:C++(静态函数)
  • 2025.9.15日软件工程学习日志
  • RocketMQ快速实战及核心概念
  • 【南方科技大学主办】第五届电气工程与机电一体化手艺国际学术会议(ICEEMT 2025)
  • 为什么不建议在 Docker 中跑 MySQL?
  • reLeetCode 热题 100-1 指针283. 移动零 - MKT
  • 解决c# DocX生成的word文档wps打开排版外边距错乱微软office正常问题
  • The 2025 ICPC Asia East Continent Online Contest (II)
  • 工厂方法模式(Factory Method) - 指南
  • 拾忆录
  • 从零搭建RAG应用:跳过LangChain,掌握文本分块、向量检索、指代消解等核心技术实现
  • python高阶技巧
  • 机器视觉之图像处理篇 - 指南
  • 尝试hikari和jdbctemplate
  • 配置Nginx根据IP地址进行流量限制以及返回JSON格式数据
  • 回归
  • CSS纯文本渐变动效
  • 泛微流程共享
  • MySQL报错:未知系统变量tx_isolation及隔离级别查询
  • Redssion