You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

创建Socket时触发Segmentation Fault段错误问题求助

问题排查与修复方案

1. 打印语句不显示的根因

标准输出stdout默认是行缓冲模式,只有遇到换行符\n、缓冲区满或者程序正常退出时才会将缓冲区内容输出到屏幕。你的代码中printf("Here I Am0")这类语句没有加换行符,内容卡在缓冲区内还没输出就触发了段错误,所以你看不到这些打印,误以为代码没执行。
修复方式:所有调试用printf末尾加\n,或者每次打印后调用fflush(stdout)强制刷新缓冲区,就能看到准确的执行位置。

2. 段错误的几个触发点

(1)日志文件指针空引用

你设置了useLog = 0,所以不会执行fopen打开日志文件,logfile一直保持初始的NULL值。如果你后续的代码(节选部分没贴出的内容)中存在fprintf(logfile, xxx)这类写入日志的操作,传入空的文件指针会直接触发段错误。
修复方式:所有对logfile的读写操作都要包裹在if (useLog == 1)的判断中,避免空指针引用。另外你当前的日志文件存在误报问题,判断文件是否打开失败的逻辑应该挪到fopen之后:

if (useLog == 1){
    printf("Using Log File\n");
    logfile = fopen("log.txt","w");
    if(!logfile)
    {
        printf("Unable to create log.txt file. \n");
    }
}
(2)socket创建失败未做校验

SOCK_RAW类型的socket即使使用sudo运行也有可能创建失败,返回值为-1。如果后续直接把非法的文件描述符传入setsockopt或者后续的收发包函数,会触发异常。
修复方式:创建socket后立刻做合法性校验:

int sock_raw = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sock_raw < 0) {
    perror("socket创建失败");
    exit(EXIT_FAILURE);
}
(3)网卡名不匹配

你代码中硬编码绑定的网卡是wlan0,现在多数Linux发行版的网卡命名规则已经变更,无线网卡常见名称是wlpXXX格式,有线网卡常见是ensXXX格式,如果网卡名不存在,setsockopt会调用失败,后续操作也可能触发异常。
修复方式:执行ip a命令查看你当前可用的网卡名称,替换代码中的wlan0,同时对setsockopt的返回值做校验:

const char* nic_name = "替换为你的实际网卡名";
if (setsockopt(sock_raw, SOL_SOCKET, SO_BINDTODEVICE, nic_name, strlen(nic_name) + 1) < 0) {
    perror("绑定网卡失败");
    close(sock_raw);
    exit(EXIT_FAILURE);
}
(4)malloc返回值未校验

你申请了65536字节的缓冲区,没有判断malloc的返回值,如果内存分配失败返回NULL,后续往缓冲区写入数据时会触发段错误。
修复方式:增加malloc校验:

unsigned char *buffer = malloc(65536);
if (buffer == NULL) {
    perror("内存分配失败");
    exit(EXIT_FAILURE);
}

调试建议

按以上方案修改后如果还有问题,可以用gdb工具定位段错误位置:

  1. 编译时加-g参数:gcc -g test.c
  2. 用gdb运行:sudo gdb ./a.out
  3. gdb内输入run启动程序,崩溃后输入bt就能看到完整的调用栈,直接定位到触发段错误的代码行。

内容的提问来源于stack exchange,提问作者Lyra Orwell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 22:54:03