首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Coredump发生在linux程序中(Redhat 8.3.1)

Coredump发生在linux程序中(Redhat 8.3.1)
EN

Stack Overflow用户
提问于 2021-08-10 12:55:53
回答 1查看 108关注 0票数 1

在我的程序中,在linux上的嵌套结构上使用_Decimal128时会出现coredump。

当满足以下所有条件时,就会发生这种情况。

首先是#pragma pack(8)声明。

第二,第三嵌套结构

第三,_Decimal128 类型address作为函数的参数。

我在找一个导致核衰竭的原因。

开发环境为Redhat 8.3.1,编译成gcc。

示例代码如下所示。

代码语言:javascript
复制
#include <stdio.h>
#pragma pack(8)   // without this line, it is success

struct _c {
    int c1;
   _Decimal128 c2;
};
struct _b {
   int b1;
   _Decimal128 b2; 
   struct _c b3;      //3rd nested structure
};
struct _a {
   int a1;
   _Decimal128 a2;
   struct _b a3;     // 2nd nested structure
};

void func1(struct _c *cptr)
{
   if (cptr->c2 == 0)     // if argument type is structure, it is success
      printf("[func1]\n");
}

void func2(_Decimal128 *ptr)
{
   if (*ptr == 0)        // if argument type is _Decimal128, it occurs coredump
      printf("[func2]\n");
}

int main()
{
   struct _a a;
   struct _b b;
   _Decimal128 t = 0;
   b.b2 = t;
   b.b3.c2 = t;
   a.a3 = b;

   func1(&a.a3.b3);  // if argument is 3rd structure address, it is success
   func2(&a.a3.b2);  // if argument is _Decimal128 address of 2rd structure, it is sunccess
   func2(&a.a3.b3.c2);  // if argument is _Decimal128 address of 3rd structure, it occurs coredump
}      

结果是,

代码语言:javascript
复制
[func1]
[func2]
Memory fault(coredump)

如果我从上面的源代码中删除#pragma pack(8)行,结果如下。

代码语言:javascript
复制
[func1]
[func2]
[func2]
EN

回答 1

Stack Overflow用户

发布于 2021-08-10 13:30:01

#pragma pack(8)会告诉编译器,结构的成员应该对齐为8个字节,而忽略了每种类型的对齐要求。

_Decimal128可能是16字节类型,其对齐要求可能是16字节.

使用指向结构struct _c *cptr的指针,编译器可以知道成员使用了非常规的对齐方式,并且可能需要某种特殊的方式来处理_Decimal128成员。

另一方面,直接使用指向_Decimal128的指针时,编译器将假定指针是指向_Decimal128成员的有效(通常对齐)指针。因此,当传递的不是指向_Decimal128的普通指针时,它可能会失败。

让我们用一些例子来验证这个语句。

首先,让我们检查一下_Decimal128成员的对齐要求和地址:

代码语言:javascript
复制
#include <stdio.h>
#pragma pack(8)   // without this line, it is success

struct _c {
    int c1;
   _Decimal128 c2;
};
struct _b {
   int b1;
   _Decimal128 b2; 
   struct _c b3;      //3rd nested structure
};
struct _a {
   int a1;
   _Decimal128 a2;
   struct _b a3;     // 2nd nested structure
};

int main(void) {
    struct _a a;
    printf("sizeof(_Decimal128) = %d\n", (int)sizeof(_Decimal128));
    printf("_Alignof(_Decimal128) = %d\n", (int)_Alignof(_Decimal128));
    printf("&a = %p\n", (void*)&a);
    printf("&a.a3.b3.c2 = %p\n", (void*)&a.a3.b3.c2);
    return 0;
}

输出的例子

代码语言:javascript
复制
sizeof(_Decimal128) = 16
_Alignof(_Decimal128) = 16
&a = 0x7fffee270d70
&a.a3.b3.c2 = 0x7fffee270da8

在这种环境中,_Decimal128的对齐要求是16字节,但是成员_Decimal128 c的地址不能被16整除。

其次,这里是@AKX示例,它显示了Decimal128可以用函数func1 (使用指向结构的指针)和函数func2 (使用指向_Decimal128的指针)进行不同的处理:

代码语言:javascript
复制
func1:
        subq    $8, %rsp
        movdqa  .LC1(%rip), %xmm1
        movdqu  8(%rdi), %xmm0
代码语言:javascript
复制
func2:
        subq    $8, %rsp
        movdqa  .LC1(%rip), %xmm1
        movdqa  (%rdi), %xmm0

在本例中,说明用于在函数func1中加载_Decimal128值。movdqu可以使用未对齐内存。

另一方面,说明用于函数func2中的_Decimal128值。movdqa在尝试使用未对齐内存时会生成一般保护异常。

这表明,在本例中,func1可以处理未对齐内存,而func2不能。

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

https://stackoverflow.com/questions/68727253

复制
相关文章

相似问题

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