HP-UX中是否存在损坏?

时间:2009-03-06 16:35:59

标签: c unix heap sigsegv

我试图了解在HP-UX 11.11中运行的程序出现了什么问题导致了SIGSEGV(11,分段错误):

(gdb) bt
#0  0x737390e8 in _sigfillset+0x618 () from /usr/lib/libc.2
#1  0x73736a8c in _sscanf+0x55c () from /usr/lib/libc.2
#2  0x7373c23c in malloc+0x18c () from /usr/lib/libc.2
#3  0x7379e3f8 in _findbuf+0x138 () from /usr/lib/libc.2
#4  0x7379c9f4 in _filbuf+0x34 () from /usr/lib/libc.2
#5  0x7379c604 in __fgets_unlocked+0x84 () from /usr/lib/libc.2
#6  0x7379c7fc in fgets+0xbc () from /usr/lib/libc.2
#7  0x7378ecec in __nsw_getoneconfig+0xf4 () from /usr/lib/libc.2
#8  0x7378f8b8 in __nsw_getconfig+0x150 () from /usr/lib/libc.2
#9  0x737903a8 in __thread_cond_init_default+0x100 () from /usr/lib/libc.2
#10 0x737909a0 in nss_search+0x80 () from /usr/lib/libc.2
#11 0x736e7320 in __gethostbyname_r+0x140 () from /usr/lib/libc.2
#12 0x736e74bc in gethostbyname+0x94 () from /usr/lib/libc.2
#13 0x11780 in dnetResolveName (name=0x400080d8 "smtp.org.com", hent=0x737f3334) at src/dnet.c:64
..

问题似乎发生在libc内部!系统调用跟踪以:

结束
Connecting to server smtp.org.com on port 25
write(1, "C o n n e c t i n g   t o   s e ".., 51) .......................... = 51
open("/etc/nsswitch.conf", O_RDONLY, 0666) ............................... [entry]
open("/etc/nsswitch.conf", O_RDONLY, 0666) ................................... = 5
  Received signal 11, SIGSEGV, in user mode, [SIG_DFL], partial siginfo
    Siginfo: si_code: I_NONEXIST, faulting address: 0x400118fc, si_errno: 0
    PC: 0xc01980eb, instruction: 0x0d3f1280
exit(11) [implicit] ............................ WIFSIGNALED(SIGSEGV)|WCOREDUMP

该计划的最后指示:

struct hostent *him;
him = gethostbyname(name); // name == "smtp.org.com" as shown by gdb

这是系统的问题,还是我错过了什么? 任何深入挖掘的指导都将受到赞赏。

THX。

4 个答案:

答案 0 :(得分:1)

每当这种情况发生在我身上时(系统库中出现意外的段错误),通常是因为我在其他地方做了一些愚蠢的事情,即缓冲区溢出,指针上的双重删除等等。

在我的错误不明显的情况下,我使用valgrind。以下内容通常就足够了:

valgrind -v --leak-check = yes --show-reachable = yes ./myprog

我认为valgrind可以在HP-UX中使用......

答案 1 :(得分:1)

您的堆栈跟踪位于malloc,这几乎肯定意味着您损坏了malloc的一个数据结构。正如previous answer所说,你可能有一个缓冲区溢出或欠载并损坏了堆中分配的一个项目。

另一种解释是你尝试对不是来自堆的东西做free,但这种可能性不大 - 可能会在free中崩溃。

答案 2 :(得分:1)

长话短说:vsnprintf在HP-UX 11.11下损坏了我的堆。 vsnprintf在C99(ISO / IEC 9899:1999)中引入,“等同于snprintf,带有变量参数列表”(§7.19.6.12.2),snprintf(§7.19.6.5.2):“如果n为零什么都写不出来。“ 那么,HP UX 11.11不符合此规范。当第二个arg == 0时,参数写在第一个arg的末尾..这当然会破坏堆(当maxsize == 0时我没有分配空格,因为没有应该是写)。

HP manual pages不清楚(“用户有责任确保有足够的存储空间。”),没有说明maxsize == 0 的情况。好陷阱..至少,手册页的警告部分应该警告符合标准的用户..

这是一个鸡蛋/鸡pb:vnsprintf是可变的,所以为了“用户的责任”确保有足够的存储可用“用户的责任”必须首先知道需要多少空间。最好的方法是是调用vnsprintf与第二个arg == 0:它应该返回所需的空间量和sprintfs没什么..好吧,除了惠普! 在此std违规下使用vnsprintf确定所需空间的一种解决方案:malloc 1个字节多于缓冲区(1st arg)并调用vnsprintf(buf + buf.length,1,..)。这只会在您分配的新字节中放置\ 0。傻,但有效。如果你在wchar条件下,malloc(sizeof ..)。

无论如何,解决方法很简单:永远不要使用maxsize == 0在HP-UX下调用v / snprintf! 我现在有一个快乐的稳定计划!

感谢所有捐助者。


在HP-UX B11.11下通过vsnprintf堆损坏 该程序在Linux / Cygwin /下打印“@@”。 它在HP-UX B11.11下打印“@ fooo @”:

#include <stdarg.h>
#include <stdio.h>

const int S=2;

void f (const char *fmt, ...) {
        va_list ap;
        int actualLen=0;
        char buf[S];

        bzero(buf, S);

        va_start(ap, fmt);
        actualLen = vsnprintf(buf, 0, fmt, ap);
        va_end(ap);

        printf("@%s@\n", buf);
}

int main () {
        f("%s", "fooo");
        return 0;
}

答案 3 :(得分:0)

读取(OS X)手册页说gethostbyname()返回一个指针,但据我所知,可能没有为该指针分配内存。你需要先malloc()吗?试试这个:

struct hostent *him = malloc(sizeof(struct hostent));
him = gethostbyname(name);
...
free(him);

这有效吗?

编辑:我测试了这个,这可能是错的。当然,我使用了裸字符串“stmp.org.com”而不是变量,但两个版本(有和没有malloc() ing)都在OS X上工作。也许HP-UX不同。