3

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

これはシステムの問題ですか、それとも何か不足していますか? より深く掘り下げるためのガイダンスをいただければ幸いです。

どうも。

4

4 に答える 4

2

簡単に言うと、vsnprintfはHP-UX11.11でヒープを破損しました。vsnprintfはC99(ISO / IEC 9899:1999)で導入され、「可変引数リストを持つsnprintfと同等です」(§7.19.6.12.2)、snprintf(§7.19.6.5.2):「nがゼロの場合、何も書かれていません」。HPUX11.11はこの仕様に準拠していません。2番目の引数==0の場合、引数は1番目の引数の最後に書き込まれます。もちろん、ヒープが破損します(maxsize == 0の場合、何も書き込まないため、スペースを割り当てません

HPのマニュアルページは不明確であり(「十分なストレージが利用可能であることを確認するのはユーザーの責任です。」)、maxsize==0の場合については何も述べられていません。素敵な罠..少なくとも、manページの警告セクションはstd準拠のユーザーに警告する必要があります。

これは卵/鶏肉のpbです:vnsprintfは可変個引数であるため、「ユーザーの責任」で十分なストレージを確保するためには、「ユーザーの責任」で最初に必要なスペースの量を知る必要があります。そのための最善の方法は、 2番目の引数を持つvnsprintf==0:必要なスペースの量を返し、sprintfsは何も返さないはずです..HPを除いて!このstd違反の下でvnsprintfを使用して必要なスペースを決定する1つの解決策:malloc 1バイト以上バッファに(1番目arg)そしてvnsprintf(buf + buf.length、1、..)を呼び出します。これにより、割り当てた新しいバイトに\ 0のみが挿入されます。愚かですが効果的です。wchar状態の場合は、malloc(sizeof ..) 。

とにかく、回避策は簡単です。maxsize==0のHP-UXでv/ snprintfを呼び出さないでください!私は今、幸せな安定したプログラムを持っています!

すべての貢献者に感謝します。


HP-UXB11.11でのvsnprintfによるヒープの破損このプログラムはLinux/Cygwin/で「@@」を出力します。HP-UXB11.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;
}
于 2009-03-10T11:35:14.947 に答える
1

あなたのスタック トレースは、mallocどこかでmallocのデータ構造の 1 つを破損したことをほぼ確実に意味します。以前の回答で述べたように、バッファ オーバーランまたはアンダーランが発生し、ヒープから割り当てられたアイテムの 1 つが破損している可能性があります。

別の説明はfree、ヒープから来ていない何かに対して実行しようとしたことですが、その可能性は低く、おそらくすぐにクラッシュしたでしょうfree

于 2009-03-06T22:18:58.240 に答える