ZBLOG

SEGV_MAPERR

SEGV_MAPERRSegmentation Fault (段错误) 的一种类型,表示程序试图访问一个 未映射(不存在)的内存地址(比如空指针解引用、越界访问等)。以下是排查和调试的方法:


1. 常见原因

  • 空指针解引用int *p = NULL; *p = 42;
  • 数组越界访问
    
    int arr[10];
    arr[100] = 5; // 越界
    
  • 使用已释放的内存
    
    int *p = malloc(sizeof(int));
    free(p);
    *p = 10; // Use-after-free
    
  • 错误的指针运算: “`c char *str = “hello”; str += 1000; // ptr now points to invalid memory *str = ‘x’; // SEGV_MAPERR

---

## **2. Debugging Methods (调试方法)**
### **(1) GDB (GNU Debugger)**
```bash
gcc -g program.c -o program   # Compile with debug symbols  
gdb ./program                # Run in GDB  

在 GDB中:

(gdb) run                     # Execute the program  
(gdb) bt                      # Print backtrace when crash occurs  
(gdb) info registers          # Check register values (e.g., `rip`/`eip`)  
(gdb) x/i $rip                # See the crashing instruction  
(gdb) x/x <address>           # Examine memory at `<address>` (if mapped)

(2) Valgrind (内存检测工具)

valgrind --tool=memcheck --leak-check=full ./program  

它会报告非法内存访问的位置,例如:

Invalid read of size X at address <addr>  

(3) Core Dump Analysis

如果程序崩溃生成了 core dump:

ulimit -c unlimited          # Enable core dumps  
./program                    # Crash happens, generates core file  
gdb ./program core.<pid>     # Analyze core dump in GDB  

3. Linux System Tools

(1) dmesg (查看内核日志)

dmesg | tail -n20            # Check recent kernel messages  

输出示例:

[12345.678] program[pid]: segfault at <address> ip <instruction_ptr> sp <stack_ptr> error <error_code>

其中 error_code=6 (SEGV_MAPERR) ,并会显示出错的地址。

(2) /proc/<pid>/maps (检查进程内存映射)

运行程序后,查看它的内存布局:

cat /proc/$(pidof program)/maps | less   

如果崩溃的地址不在任何合法区间(如堆、栈、共享库),则说明是非法访问。


4. Signal Handler (捕获错误地址)

可以在代码里注册信号处理函数,打印出错时的信息:

#include <signal.h>
#include <stdio.h>
#include <execinfo.h>

void segv_handler(int sig, siginfo_t *info, void *ucontext) {
    fprintf(stderr, "Segmentation fault at: %p\n", info->si_addr);

    // Print stack trace for debugging (-rdynamic required)
    void *array[10];
    size_t size = backtrace(array, sizeof(array)/sizeof(void*));
    backtrace_symbols_fd(array, size, STDERR_FILENO);

    _exit(1);
}

int main() {
    struct sigaction sa;
    sa.sa_sigaction = segv_handler;
    sa.sa_flags = SA_SIGINFO;
    sigaction(SIGSEGV, &sa, NULL);

    // Your code here...
}

5. Example Fixes

修复空指针解引用:

int *p = NULL;
if (p != NULL) {   // Add NULL check!
*p =42;
}

修复数组越界:

int arr[10];
if(index >=0 && index<10){//Bounds checking!
arr[index]=5;
}

避免 Use-After-Free:

int*p=malloc(sizeof(int));
free(p);
p=NULL;//Prevent dangling pointer usage!

总结

Method Usage
GDB Interactive debugging
Valgrind Detect memory errors
Core Dump Post-mortem analysis
dmesg Kernel logs
/proc/maps Check process memory layout
Signal Handler Catch SEGV in code

通过以上方法可以精准定位导致 SEGV_MAPERR(非法内存访问)的原因。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://sdn.0voice.com/?id=8052

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?