首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读/写无效会导致SIGBUS错误吗?

读/写无效会导致SIGBUS错误吗?
EN

Stack Overflow用户
提问于 2019-06-25 17:06:59
回答 1查看 1.1K关注 0票数 2

编辑1:Platform是示例程序的x86_64。

编辑2:我正在编辑这个以更好地理解。以下是两个不同的问题。第一个问题是,无效的读写是否会导致SIGBUS?第二个问题是,瓦兰对SIGBUS分析有用吗?示例代码用于支持我的观点的第二个问题,即在SIGBUS错误的情况下,Val差尔将根本没有用处。我可能错了。

实际场景:我们有一个屏幕阅读器应用程序,它在连续测试2天后崩溃(一旦由于SIGBUS而崩溃)。我有一个coredump文件,但是我没有正确的二进制和调试包。因此,本质上,我必须在不同的二进制文件中测试这一点,而且由于调试包中的不匹配,coredump在gdb中无法正常工作。在分析过程中,我可以看到屏幕阅读器模块中有一些无效的读/写。我的队友建议,通过修复这些无效的读/写可以解决这个问题,但我认为它不会解决这个问题。下面是我对这两个信号的理解。

SIGSEGV:地址是有效的,但读/写权限不存在。

SIGBUS:地址本身是无效的(由于误用等原因无法找到地址)

我有个关于SIGBUS信号的问题。我在堆栈溢出上搜索过类似的问题,但没有找到任何明确的答案。

可以无效读写导致总线错误(SIGBUS)?

我的理解是,无效的读/写总是会导致分段错误(SIGSEGV),修复总线错误的最佳方法是在应用程序上运行gdb。在发生公共汽车错误的情况下,压磨分析是毫无帮助的。下面的代码更详细地解释了这一点。

代码语言:javascript
复制
#include<stdlib.h>
#include<stdio.h>

typedef struct {
char *name;
int val;
}data;

void fun1()
{
    data *ptr = malloc(sizeof(data));
    ptr->val = 100;
    ptr->name = "name in structure";

    printf("val:%d name:%s\n",ptr->val,ptr->name);
    free(ptr);
    ptr = NULL;
    printf("val:%d name:%s\n",ptr->val,ptr->name); //SIGSEGV
    return;
}

int fun2()
{
    #if defined(__GNUC__) 
    # if defined(__i386__) 
    /* Enable Alignment Checking on x86 */
    __asm__("pushf\norl $0x40000,(%esp)\npopf"); 
    # elif defined(__x86_64__)  
    /* Enable Alignment Checking on x86_64 */
    __asm__("pushf\norl $0x40000,(%rsp)\npopf"); 
    # endif 
    #endif 

    char *cptr = malloc(sizeof(int) + 1);
    char *optr = cptr;
    int *iptr = (int *) ++cptr; 
    *iptr = 42; //SIGBUS
    free(optr);

    return 0; 
}

void fun()
{
    fun2();
    //fun1();
}

int main()
{
    fun();
    return 0;
}

在分割错误的情况下,Val砂矿报告将有导致崩溃的代码的详细信息,但是如果SIGBUS崩溃,我在Val差尔报告中没有找到任何这样的细节。

SIGSEGV的价值报告:

代码语言:javascript
复制
==28128== Memcheck, a memory error detector
==28128== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28128== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==28128== Command: ./a.out
==28128== Parent PID: 27953
==28128== 
==28128== Invalid read of size 8
==28128==    at 0x400619: fun1 (tmp.c:18)
==28128==    by 0x400695: fun (tmp.c:46)
==28128==    by 0x4006A6: main (tmp.c:51)
==28128==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==28128== 
==28128== 
==28128== Process terminating with default action of signal 11 (SIGSEGV)
==28128==  Access not within mapped region at address 0x0
==28128==    at 0x400619: fun1 (tmp.c:18)
==28128==    by 0x400695: fun (tmp.c:46)
==28128==    by 0x4006A6: main (tmp.c:51)
==28128==  If you believe this happened as a result of a stack
==28128==  overflow in your program's main thread (unlikely but
==28128==  possible), you can try to increase the size of the
==28128==  main thread stack using the --main-stacksize= flag.
==28128==  The main thread stack size used in this run was 8388608.
==28128== 
==28128== HEAP SUMMARY:
==28128==     in use at exit: 0 bytes in 0 blocks
==28128==   total heap usage: 2 allocs, 2 frees, 1,040 bytes allocated
==28128== 
==28128== All heap blocks were freed -- no leaks are possible
==28128== 
==28128== For counts of detected and suppressed errors, rerun with: -v
==28128== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

SIGBUS的价值报告:

代码语言:javascript
复制
==28176== Memcheck, a memory error detector
==28176== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28176== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==28176== Command: ./a.out
==28176== Parent PID: 27953
==28176== 
==28176== 
==28176== HEAP SUMMARY:
==28176==     in use at exit: 0 bytes in 0 blocks
==28176==   total heap usage: 1 allocs, 1 frees, 5 bytes allocated
==28176== 
==28176== All heap blocks were freed -- no leaks are possible
==28176== 
==28176== For counts of detected and suppressed errors, rerun with: -v
==28176== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-25 17:56:45

代码语言:javascript
复制
int *iptr = (int *) ++cptr; 
*iptr = 42; //SIGBUS

违反C标准的多个部分。

你这是在和,第7段发生冲突

指向对象类型的指针可以转换为指向不同对象类型的指针。如果结果指针未针对引用类型正确对齐,则行为未定义。

也违反了,第7段的严格混叠规则。

对象的存储值只能由具有下列类型之一的lvalue表达式访问:

  • 与对象的有效类型兼容的类型,
  • 与对象的有效类型兼容的类型的限定版本,
  • 与对象的有效类型对应的有符号或无符号类型的类型,
  • 对象的有效类型的限定版本对应的有符号或无符号类型的类型,
  • 在其成员中包含上述类型之一的聚合或联合类型(递归地包括次聚合或包含的联合的成员),或
  • 字符类型。

Memcheck的Valgrind文档

4.1.概述 Memcheck是一个内存错误检测器。它可以检测C和C++程序中常见的下列问题。

  • 访问您不应该访问的内存,例如溢出和运行堆块,超过堆栈顶部,以及在释放后访问内存。
  • 使用未定义的值,即未初始化的值或从其他未定义的值派生的值。
  • 不正确地释放堆内存,例如双释放堆块,或者使用malloc/new/new[]与free/delete/delete[]不匹配
  • 在memcpy和相关函数中重叠src和dst指针。
  • 将可疑(可能为负值)值传递给内存分配函数的大小参数。
  • 内存泄漏。

注意,您的代码

代码语言:javascript
复制
int *iptr = (int *) ++cptr; 
*iptr = 42; //SIGBUS

没有任何一件事情是瓦伦声称要探测到的。您没有访问内存的权限,也没有访问malloc()创建区域界限之外的内存。您还没有free()d内存。您没有未初始化的变量,您不是双free()内存,也不是对重叠的源区域和目标区域不正确地使用memcpy()。您也没有将负/“可疑”大小传递给分配函数。而且您也没有泄漏任何内存。

所以,没有,瓦兰甚至没有声称能够检测到会导致SIGBUS的代码。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56758924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档