2

背景情報:

ネットワーク クラスのグループ プロジェクトに取り組んでいます。3 つの部分からなるキー配布センターを実装します。KDC 自体、イニシエーター (A) とレスポンダー (B) は、大学が所有する RedHat 6 サーバー上で c++ と g++ を使用します。

このPractical Socketsライブラリを使用してきましたが、比較的順調に進んでいます。

問題:

私のパートナーと私は、具体的にはfillAddr() 関数で Unix の gethostbyname() 関数を呼び出すと、segfaults が発生し始めました。

// Function to fill in address structure given an address and port
static void fillAddr(const string &address, unsigned short port, 
                     sockaddr_in &addr) {
  memset(&addr, 0, sizeof(addr));  // Zero out address structure
  addr.sin_family = AF_INET;       // Internet address

  hostent *host;  // Resolve name
  if ((host = gethostbyname(address.c_str())) == NULL) { /* offending line */
    // strerror() will not work for gethostbyname() and hstrerror() 
    // is supposedly obsolete
    throw SocketException("Failed to resolve name (gethostbyname())");
  }
  addr.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);

  addr.sin_port = htons(port);     // Assign port in network byte order
}

valgrind、GDB、「cout s」などを使用してデバッグしましたが、マイナスの進歩を遂げています。GDB のバックトレースからわかることは次のとおりです (サーバー名は検閲され、典型的な "server.college.edu" アドレスが使用されています)。

Program received signal SIGSEGV, Segmentation fault.
0x00000039b1a7621b in malloc_consolidate () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.107.el6.x86_64 libgcc-4.4.7-3.el6.x86_64 libstdc++-4.4.7-3.el6.x86_64
(gdb) backtrace
#0  0x00000039b1a7621b in malloc_consolidate () from /lib64/libc.so.6
#1  0x00000039b1a79385 in _int_malloc () from /lib64/libc.so.6
#2  0x00000039b1a7a911 in malloc () from /lib64/libc.so.6
#3  0x00000039b1b03265 in gethostbyname () from /lib64/libc.so.6
#4  0x00000000004033f7 in fillAddr (address="KDC", port=9284, addr=...)
    at PracticalSocket.cpp:72
#5  0x0000000000404484 in UDPSocket::sendTo (this=0x7fffffffe410, buffer=0x6102a0, bufferLen=40, foreignAddress=
    "KDC", foreignPort=9284) at PracticalSocket.cpp:299
#6  0x00000000004085e2 in sendRecv (sock=..., message="2007|137.28.8.164|SERVER_B|1234", addr=
    "KDC", port=9284) at initiator.cpp:144
#7  0x0000000000407a3f in getSessionKey (sock=..., kdc_addr=0x40aa84 "KDC",
    resp_addr=0x40aa98 "RESPONDER", nonce="1234") at initiator.cpp:88
#8  0x0000000000407546 in main (argc=1, argv=0x7fffffffe548) at initiator.cpp:49

否定的な進歩について説明しましょう:

追加の std::cout などの小さな変更だけで、コンパイル、テスト、デバッグなどを行うほど、コードの実行が少なくなるようです。この fillAddr() 関数は、少なくとも最初は数回使用され、成功しています。malloc_consolidate() による segfault が確実に発生するようになりました。

現在の状況は次のとおりです。

*** glibc detected *** ./kdc: malloc(): memory corruption: 0x000000000132b7d0 ***

*** glibc detected *** ./kdc: malloc(): memory corruption: 0x000000000132b7d0 ***

...


*** glibc detected *** ./kdc: malloc(): memory corruption: 0x000000000132b7d0 ***

これで、KDC のコンソール ウィンドウがいっぱいになります。

どんな助けでも大歓迎です。さらに詳しい情報が必要な場合は、お知らせください。

4

1 に答える 1

4

-type 関数の内部でクラッシュしている場合は、mallocほぼ確実にメモリ領域が破損しています。

ある時点で、(たとえば) 30 バイトを割り当て、60 バイトのデータで埋めようとしたとします。

この問題の根本原因を追跡する必要がありますが、残念ながら、表示されたコードにはありませんを呼び出す前の不確定な時点で、独自のコードにある可能性がはるかに高くなりますgethostbyname()。ヒープ メモリを割り当てて書き込みを行う場所を探します。

あなたの「マイナス」の進歩は、この種の問題の良い兆候でもあります.

于 2013-04-10T02:39:22.193 に答える