*** 检测到堆栈粉碎 ***:使用 HEALPix C 子例程终止中止(核心转储)

*** stack smashing detected ***: terminated Aborted (core dumped) using HEALPix C subroutines

我正在尝试将 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);

}

但是,这段代码returns出错了:

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 程序中。

如果你勾选 related documentation :

read_healpix_map

This routine reads a full sky HEALPix map from a FITS file

Location in HEALPix directory tree: src/C/subs/read_healpix_map.c

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

ARGUMENTS

 | name&dimensionality  | kind | in/out | description     |

   read_healpix_map       float   OUT     array containing the map read from the file 

   infile                 char    IN      FITS file containing a full sky to be read

   nside                   long   OUT     HEALPix resolution parameter of the map

   coordsys                char   OUT     astronomical coordinate system of 
 pixelisation (either 'C', 'E' or 'G' standing respectively for Celestial=equatorial, Ecliptic or Galactic) 

   ordering                char   OUT     HEALPix pixel ordering (either 'RING' or 'NESTED')

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

使用 char coordsys[]="G";char order[]="NESTED";,您是在程序的数据部分定义字符串。当您使用最长的字符串进行排序时,您应该为两个字符串提供足够的 space。

但是

read_healpix_map 文档不准确。该函数将在其 coordsysordering 参数中存储 TSTRING object,作为这些参数中的 its source calls the fits_read_key function which store a TSRING object

这就是使用 'big size' 缓冲区有效的原因。

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

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