【问题标题】:*** stack smashing detected ***: terminated Aborted (core dumped) using HEALPix C subroutines*** 检测到堆栈粉碎***:使用 HEALPix C 子例程终止中止(核心转储)
【发布时间】:2021-08-26 09:39:24
【问题描述】:

我正在尝试将 python 代码转换为 C 代码。所以我试图翻译那行:

import healpy as hp  
OldTobySensitivMap = hp.read_map('file.fits', dtype=numpy.float64)

这将使用 HEALPix 投影打开一个 FITS 文件。所以在 C 中我使用的是 HEALPIx 库:

#include "chealpix.h"
#include "fitsio.h"
#include <string.h>

int main(int argc, char **argv){

        char coordsys[]="G";
        char order[]="NESTED";
        long nside=0;
        float *map;
        map=read_healpix_map("file.fits",&nside,coordsys,order);
        printf("nside:%ld, coordsys:%s, order:%s",nside,coordsys,order);     

return(0);

}

但是,此代码返回错误:

WARNING: Could not find COORDSYS keyword in in file file.fits
*** stack smashing detected ***: terminated
Program received signal SIGABRT, Aborted.

GDB 调试器输出为:

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff76f5859 in __GI_abort () at abort.c:79
#2  0x00007ffff77603ee in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff788a07c "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:155
#3  0x00007ffff7802b4a in __GI___fortify_fail (msg=msg@entry=0x7ffff788a064 "stack smashing detected") at fortify_fail.c:26
#4  0x00007ffff7802b16 in __stack_chk_fail () at stack_chk_fail.c:24
#5  0x00005555555556af in main (argc=1, argv=0x7fffffffdd18) at young_pulsar_pop.c:60

增加字符串的大小使得:

        char coordsys[2024]="G";
        char order[2024]="NESTED";

工作,但是输出是nside:512, coordsys:, order:RING,所以我不太明白是什么导致了堆栈错误。

就像其他用户所说的那样,HEALPix 接口对于 C 来说似乎很不安全,而且文档真的很差。因此,我想知道我是否不应该简单地将 python 代码嵌入到我的 C 程序中。

【问题讨论】:

    标签: python c stack coredump healpy


    【解决方案1】:

    如果您检查related documentation

    read_healpix_map

    此例程从 FITS 文件中读取全天空 HEALPix 地图

    HEALPix 目录树中的位置:src/C/subs/read_healpix_map.c

    FORMAT float *read_healpix_map(char *infile, long *nside, char *coordsys, char *ordering)

    论据

    |名称和维度 |种类 |进/出 |描述 | read_healpix_map float OUT 数组,包含从文件中读取的地图 infile char IN FITS 包含要读取的完整天空的文件 nside long OUT HEALPIx 地图的分辨率参数 coordsys char OUT 天文坐标系 像素化(“C”、“E”或“G”分别代表天体=赤道、黄道或银河) ordering char OUT HEALPIx 像素排序(“RING”或“NESTED”)

    我们看到coordsysordering是这个函数的输出参数。这意味着此函数期望具有定义大小的字符缓冲区来存储相关的输出字符串。如本文档中所述,coordsys 提供的缓冲区应该是,对于 ASCII 字符串char [2] 类型(将坐标系存储在一个字符加上 NULL 字节)和 ordering 应该是char [7] 类型(最长的字符串是 'NESTED',6 个字符加上 NULL 字节)。

    使用char coordsys[]="G";char order[]="NESTED";,您可以在程序的数据部分定义字符串。当您使用最长的字符串进行排序时,您应该为这两个字符串留出足够的空间。

    但是。

    read_healpix_map 文档不准确。该函数将在其coordsysordering 参数中存储一个TSTRING 对象,因为its source 调用fits_read_key 函数,而store a TSRING object 在这些参数中。

    这就是使用“大尺寸”缓冲区有效的原因。

    为了避免任何麻烦,您可以做的最好的事情是直接使用“G”和“NESTED”的TSTRING 对象来初始化缓冲区coordsysorder。在fitsio.h 标头documentation 中,关键字的最大长度用FLEN_VALUE 定义。所以我建议你使用:

    char coordsys[FLEN_VALUE]="G";
    char order[FLEN_VALUE]="NESTED";
    

    【讨论】:

    • 好的,非常感谢@Zilog80!我应该如何在 C 中使用 tstring?我以前从未听说过这种类型。
    • 只需编辑建议您使用预定义的FLEN_VALUE 作为缓冲区大小。
    • 好地方。初始化是我在之前的问题stackoverflow.com/questions/67841262/… 中建议的。我在文档中工作的地方从未遇到过这个库。我确实注意到那里的文档很差,并建议在 cmets 中使缓冲区任意大以查看其中放置的内容。
    • @Clifford 文档可能会更好,是的。但是,他们的代码不应使用输出参数缓冲区来进行字符串操作。你认为我们应该通知他们更新他们的文档,如果不是图书馆吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多