当-lm静态链接时,运行时的分段错误 - 在64位AMD上的14.04.1 LTS上转储核心

时间:2015-04-01 04:10:43

标签: c ubuntu gcc

C中的代码在64位AMD C50x2上的Ubuntu 14.04.1 LTS上运行良好。当“-lm”静态链接并在同一环境中运行相同的测试时,它会在运行时转储核心。它还通过了ldd测试。 只有更改的内容是“-lm”静态链接

gcc .... -static -lm 后来尝试使用“-lm”库的完整路径 - 它再次转储核心。

尝试使用trace命令:

execve("./mypro", ["./mypro"], [/* 61 vars */]) = 0
uname({sys="Linux", node="Acer", ...})  = 0
brk(0)                                  = 0x2668000
brk(0x26691c0)                          = 0x26691c0
arch_prctl(ARCH_SET_FS, 0x2668880)      = 0
readlink("/proc/self/exe", "/home/owner/wfiles/mypro", 4096) = 23
brk(0x268a1c0)                          = 0x268a1c0
brk(0x268b000)                          = 0x268b000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
write(2, "Expecting two argume"..., 35Expecting two argument
) = 35
exit_group(1)                           = ?
+++ exited with 1 +++ 

更新: 1)我只有一个图书馆。另外,我编译的订单:

gcc a.c b.c -o myprogramEXE -static -lm

2)我运行了gdb和bactrace - 问题可能与Linux和malloc有关。部分代码取自C(NRC)中的Numerical Recipie,它使用了 -

void    *malloc(int);

它与Linux不兼容,取而代之的是,我添加了另一个包含文件。分段故障发生在NRC下面的这个函数中,它表示free():

void free_vector(v,nl,nh)
float *v;
int nl, nh;
/* Frees a float vector allocated by vector().    */
{
    free((char*) (v+nl)); 
}

NRC使用以下函数创建向量:

float *vector (nl,nh)
int nl, nh;
{
    float *v;

    v=(float *)malloc((unsigned) (nh-nl+1)*sizeof(float));
    if (!v) nrerror("allocation failure in vector()");
    return v-nl;
}

如何解决问题 - 为什么在同一个构建环境中存在静态链接时会发生这种情况?

UPDATE2: 我在NRC网站上找到了修改后的代码 - 但是我的问题没有得到解决。 http://www.nr.com/pubdom/nrutil.c.txt

void free_vector(float *v, long nl, long nh)
/* free a float vector allocated with vector() */
{
    free((char*) (v+nl-1));
}

float *vector(long nl, long nh)
/* allocate a float vector with subscript range v[nl..nh] */
{
    float *v;

    v=(float *)malloc((size_t) ((nh-nl+1+1)*sizeof(float)));
    if (!v) nrerror("allocation failure in vector()");
    return v-nl+1;
}

2 个答案:

答案 0 :(得分:3)

return v-nl;导致未定义的行为。

指针可能只指向数组的元素(或者指向最后一个元素的元素)。写v - nl试图形成一个指向中间的指针。

重新设计此代码不依赖于未定义的行为是个好主意。


你提到void *malloc(int);,但那会是一个错误。正确的签名是void *malloc(size_t);

在任何情况下,您都应该写#include <stdlib.h>,以避免出现任何错误。

答案 1 :(得分:0)

它可能在一种情况下(与-static -lm链接)转储核心的原因是链接已经改变了内存布局 - 但程序仍然行为不端,只是以一种不明显的方式(但是。 )

我没有“C中的数字接收”,但是如果你已经将代码示例重新输入到你自己的程序中,我怀疑是一个打字错误。

在你的“free_vector(float * v,int nl,int nh)”例子中,'v'是一个“浮动”的一维数组。你对“free()”的调用中的表达式“v + nl”与“&amp;(v [nl])”相同 - 即:你试图释放数组的'nl'元素没有多大意义。 (如果'v'是浮点数的POINTERS数组,那就有意义,但是'v'会被声明为“float * v []”或“float ** v”。)

我假设'v'(由“vector()”分配)应该是浮点数的一维数组(向量)或指向浮点数的指针(这还不确定。)'nl'和'nh '似乎是数组(向量)索引边界,因此您可以将数组从1到n而不是0到n-1(或其他一些范围,如5到9)和“vector()”函数进行处理分配'v'。除此之外,我无法猜测。