C语言程序可能导致Linux系统卡死或卡顿的场景主要包括内存泄漏、死锁、CPU资源耗尽、硬件交互问题和文件I/O阻塞。
linux用户态问题场景分析
1,内存问题
查看进程内存使用情况,ps aux
cat /proc/pid/status以及其他内存相关信息
cat /proc/smaps
2,死锁/CPU资源耗尽
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
void* thread1(void* arg) {
pthread_mutex_lock(&mutex1);
printf("Thread1: Locked mutex1\n");
pthread_mutex_lock(&mutex2); // 等待mutex2
printf("Thread1: Locked mutex2\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
return NULL;
}
void* thread2(void* arg) {
pthread_mutex_lock(&mutex2);
printf("Thread2: Locked mutex2\n");
pthread_mutex_lock(&mutex1); // 等待mutex1
printf("Thread2: Locked mutex1\n");
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex2);
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}
使用top/perf top -g火焰图分析// cpu_hog.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
printf("CPU Hog process started. PID: %d\n", getpid());
printf("This process will consume 100%% of one CPU core.\n");
printf("Press Ctrl+C to stop it.\n");
// 一个简单的无限循环,持续消耗CPU
while (1) {
// 空循环体,什么也不做,就是占用CPU时间
// 为了防止编译器优化掉这个循环,可以加一个小的计算
volatile int dummy = 0;
for (int i = 0; i < 100000; ++i) {
dummy += i;
}
}
return 0;
}
可以看到cpu运行差不多达到了100%.
gdb工具分析卡死的进程。
strace分析进程
3,文件I/O阻塞,同步write()大文件
使用strace查看阻塞进程相关信息,并且查看i/o通信过程中的errno信息打印出来进行错误码分析,或者查看进程状态为 D状态。// io_hog.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define BUFFER_SIZE (4 * 1024 * 1024) // 4MB buffer
#define FILE_SIZE (1024 * 1024 * 1024) // 1GB file
int main() {
printf("I/O Hog process started. PID: %d\n", getpid());
printf("This process will write a 1GB file synchronously.\n");
int fd = open("large_file.dat", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
perror("open");
return 1;
}
char *buffer = malloc(BUFFER_SIZE);
if (!buffer) {
perror("malloc");
close(fd);
return 1;
}
memset(buffer, 'A', BUFFER_SIZE);
size_t total_written = 0;
while (total_written < FILE_SIZE) {
// write() 是一个同步阻塞调用
// 它会等待数据从用户空间拷贝到内核空间页缓存,
// 并且默认情况下,会等待数据真正写入磁盘(或至少被内核调度写入)才返回。
ssize_t bytes_written = write(fd, buffer, BUFFER_SIZE);
if (bytes_written == -1) {
perror("write");
break;
}
total_written += bytes_written;
}
printf("Finished writing %zu bytes.\n", total_written);
free(buffer);
close(fd);
return 0;
}
查看进程是否进去了D状态,如果是可以使用开启hungtask监控进程状态进行分析。
使用iostat查看I/O等待时间
使用strace查看调用关系。
linux内核态问题场景分析
1,内存分析
slabinfo/meminfo/page fault内存分析
dmesg | grep “page fault”
2,死锁/softlockdep/hardlockdep/
cat /proc/sys/watchdog
cat /proc/sys/soft_watchdog
cat /proc/sys/hard_watchdog
cat /proc/sys/soft_watchdog_panic
cat /proc/sys/hard_watchdog_panic
自旋锁卡死问题场景举例分析
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/kernel.h>
static spinlock_t lock1;
static spinlock_t lock2;
void thread1(void) {
spin_lock(&lock1);
printk(KERN_INFO "Thread1: Locked lock1\n");
spin_lock(&lock2); // 尝试获取lock2,但lock2已被Thread2持有
printk(KERN_INFO "Thread1: Locked lock2\n");
spin_unlock(&lock2);
spin_unlock(&lock1);
}
void thread2(void) {
spin_lock(&lock2);
printk(KERN_INFO "Thread2: Locked lock2\n");
spin_lock(&lock1); // 尝试获取lock1,但lock1已被Thread1持有
printk(KERN_INFO "Thread2: Locked lock1\n");
spin_unlock(&lock1);
spin_unlock(&lock2);
}
卡死场景举例:
#include <linux/module.h>
#include <linux/kernel.h>
void busy_loop(void) {
while (1) {
// 忙等待,不释放CPU
}
}
lockdep工具使用/watchdog /hungtask分析
3,中断风暴
cat /proc/interrupt,查看是否有很多的异常中断信息。
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/kernel.h>
irqreturn_t high_freq_interrupt(int irq, void *dev_id) {
while (1) {
// 模拟高频中断处理
printk(KERN_INFO "Handling interrupt...\n");
}
return IRQ_HANDLED;
}
static int __init storm_init(void) {
// 注册一个中断处理程序
request_irq(10, high_freq_interrupt, IRQF_SHARED, "storm_handler", &high_freq_interrupt);
printk(KERN_INFO "Interrupt storm module loaded\n");
return 0;
}
static void __exit storm_exit(void) {
free_irq(10, &high_freq_interrupt);
printk(KERN_INFO "Interrupt storm module unloaded\n");
}
module_init(storm_init);
module_exit(storm_exit);
MODULE_LICENSE("GPL");
4,硬件交互问题
dmesg/cat /proc/kmsg &查看是否有异常信息
654

被折叠的 条评论
为什么被折叠?



