为什么套接字在gdb下失败?

时间:2012-07-16 02:27:12

标签: c++ windows gdb winsock

gdb下突然socket崩溃(但正常工作正常)。这只发生在我初始化winsock时。非常感谢任何帮助。

#include <stdlib.h>
#include <stdio.h>
#include <locale.h>

#include <winsock2.h>
#include <Iphlpapi.h>
#ifdef _MSC_VER
    #pragma comment(lib, "ws2_32.lib")
    #pragma comment(lib, "IPHLPAPI.lib")
#endif
#include <windows.h>

unsigned char Network_isInitialized_ = 0;

#define SYSTEMINFORMATION_ISNATIVEWINDOWS 1

unsigned char Network_init_(){
#if SYSTEMINFORMATION_ISNATIVEWINDOWS
    if (Network_isInitialized_){
        return Network_isInitialized_;
    }
    WSADATA wsadata;
    int error = WSAStartup(0x0202, &wsadata);
    Network_isInitialized_ = error == 0 ? 1 : 0;
    return Network_isInitialized_;
#else
    return 1;
#endif
}

void Network_shutdown_(){
#if SYSTEMINFORMATION_ISNATIVEWINDOWS
    if (Network_isInitialized_){
        WSACleanup(); //Clean up Winsock
    }
    Network_isInitialized_ = 0;
#else
    //Unix doesnt need to do anything
#endif
}


typedef struct TCP_Connection_s {
    char *name;
    int port;
    unsigned int ip;

    struct sockaddr_in *connection;
    void *ptr;
    unsigned int socket;
} TCP_Connection;

TCP_Connection* TCP_Connection_malloc(){
    TCP_Connection *connection = (TCP_Connection*)malloc(sizeof(TCP_Connection));
    memset(connection, 0, sizeof(*connection));
    connection->connection = (struct sockaddr_in*) malloc (sizeof(struct sockaddr_in));
    memset(connection->connection, 0, sizeof(*connection->connection));
    return connection;
}

TCP_Connection* myconnect(TCP_Connection *connection){
    if (connection == NULL){
        return NULL;
    }
    connection->socket = socket(AF_INET, SOCK_STREAM, 0);
    if (connection->socket+1 == 0){
        return NULL;
    }
    int ret = connect(connection->socket, (struct sockaddr *)connection->connection, sizeof(*connection->connection));
    if (ret != 0){
        return NULL;
    }
    return connection;
}

TCP_Connection* connectToHost(TCP_Connection *connection, char *address, int port){
    if (address == NULL){
        return NULL;
    }

    if (connection == NULL){
        connection = TCP_Connection_malloc();
    }

    struct hostent *he = (struct hostent *) gethostbyname(address);
    int retryCount = 5;
    while (he == NULL && retryCount > 0){
        he = (struct hostent *) gethostbyname(address);
        Sleep(2000);
        retryCount = retryCount - 1;
    }
    if (he == NULL){
        return NULL;
    }
    struct sockaddr_in temp;
    memcpy(&(temp.sin_addr), he->h_addr, he->h_length);

    connection->connection->sin_family = AF_INET;
    connection->connection->sin_addr.s_addr = INADDR_ANY;
    connection->connection->sin_port = htons(port);
    connection->port = port;

    memcpy(&(connection->connection->sin_addr), he->h_addr, he->h_length);
    return myconnect(connection);
}


int main(int argc, char *argv[]){
    //Random_seedCryptographic();
    Network_init_();
    connectToHost(NULL, "localhost", 1337);
    Network_shutdown_();
    printf("Press any key to continue...");
    fflush(0);
    getchar();
    return 0;
}
$ gdb test.exe
GNU gdb (GDB) 7.3.50.20111026-cvs (cygwin-special)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-cygwin".
For bug reporting instructions, please see:
...
Reading symbols from /cygdrive/c/test.exe...done.
(gdb) run
Starting program: /cygdrive/c/test.exe
[New Thread 201280.0x60b68]
dll path too long
[New Thread 201280.0x304b0]
warning: Could not load shared library symbols for //./globalroot/systemroot/syswow64/mswsock.dll.
Do you need "set solib-search-path" or "set sysroot"?

Program received signal SIGTRAP, Trace/breakpoint trap.
0x3567125a in ?? () from /cygdrive/c/Windows/syswow64/mswsock.dll
(gdb) bt
#0  0x3567125a in ?? () from /cygdrive/c/Windows/syswow64/mswsock.dll
#1  0x753b8b9d in inet_ntoa () from /cygdrive/c/Windows/syswow64/WS2_32.dll
#2  0x753b8972 in inet_ntoa () from /cygdrive/c/Windows/syswow64/WS2_32.dll
#3  0x753b89da in inet_ntoa () from /cygdrive/c/Windows/syswow64/WS2_32.dll
#4  0x753b3d70 in WSCInstallProvider ()
   from /cygdrive/c/Windows/syswow64/WS2_32.dll
#5  0x00000002 in ?? ()
#6  0x00000001 in ?? ()
#7  0x00000000 in ?? ()
(gdb)

更新:我尝试在mingw portable下的另一个系统上编译同一个文件并且有效。然后我尝试在我的系统上安装mingw并卸载cygwin ......仍然无法正常工作XD

1 个答案:

答案 0 :(得分:0)

这是因为Cygwin尝试模拟UNIX环境,而您不需要在UNIX上调用WSAStartup()。 Cygwin会自动执行此操作,因此您将重复Winsock的初始化/清理。例如,请参阅this