2010-10-04 38 views
1

好的,我完全處於虧損狀態。 有一小部分用戶在我的主機名轉換中似乎有BAD_ACCESS錯誤。BAD_ACCESS對getaddrinfo期間的用戶數量很少

完全崩潰如下:

Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: 0x000000000000000d, 0x0000000000000000 
Crashed Thread: 21 

Thread 21 Crashed: 
0 libSystem.B.dylib    0x00007fff8406a446 _mdns_query_callback + 275 
1 libSystem.B.dylib    0x00007fff84057fc8 handle_query_response + 296 
2 libSystem.B.dylib    0x00007fff84057433 DNSServiceProcessResult + 717 
3 libSystem.B.dylib    0x00007fff84069cf3 _mdns_query_mDNSResponder + 1180 
4 libSystem.B.dylib    0x00007fff84069090 _mdns_search + 1458 
5 libSystem.B.dylib    0x00007fff840682f1 _mdns_addrinfo + 716 
6 libSystem.B.dylib    0x00007fff84067373 search_addrinfo + 146 
7 libSystem.B.dylib    0x00007fff84066d9c si_addrinfo + 1352 
8 libSystem.B.dylib    0x00007fff840667ad getaddrinfo + 159 
9 com.NZBVortex.NZBVortex   0x000000010002a4d7 -[CFNetworkStream getHostAddress:sockAddressIn:] + 152 
10 com.NZBVortex.NZBVortex   0x000000010002a622 -[CFNetworkStream openBSDSocket::] + 252 

下面是我用解析DNS(重要部件)的代碼。 我在這裏錯過了什麼;我可以添加更多支票嗎? 這只是一個非常低的用戶數量,所以成千上萬沒有問題。我的主機名解析代碼

部分: 我[CFNetworkStream openBSDSocket ::]方法

-(bool)openBSDSocket:(NSString*)hostName:(int)port { 
    struct sockaddr_in remoteAddr; 

    remoteAddr.sin_family = AF_INET; 
    remoteAddr.sin_port = htons(port); 

    if ([self getHostAddress:hostName sockAddressIn:&remoteAddr]) { 
     //some non-related code 
    } 
} 

這反過來又調用[自我getHostAddress:XXXX]方法 下面的完整方法:

-(bool)getHostAddress:(NSString*)hostname sockAddressIn:(struct sockaddr_in*)result { 
    struct addrinfo hints, *res, *iterateRes; 
    int retval; 

    memset (&hints, 0, sizeof (struct addrinfo)); 
    hints.ai_family = PF_UNSPEC; 
    hints.ai_socktype = SOCK_STREAM; 
    hints.ai_flags |= AI_CANONNAME; 

    int maxLength = [hostname length]+1; 
    const char hostNameC[maxLength]; 
    struct in_addr *inAddr; 
    bool foundAddress = NO; 

    if (hostNameC!=NULL) { 
     [hostname getCString:(void*)&hostNameC maxLength:maxLength encoding:NSASCIIStringEncoding]; 

     retval = getaddrinfo (hostNameC, NULL, &hints, &res); 
     if (retval == 0) { 

      iterateRes = res; 
      while (iterateRes && !foundAddress) { 
       switch (iterateRes->ai_family) 
       { 
        case AF_INET: 
         inAddr = &((struct sockaddr_in *) iterateRes->ai_addr)->sin_addr; 
         memcpy(&(result->sin_addr), inAddr, sizeof(inAddr)); 
         foundAddress = YES; 
       } 
       iterateRes = iterateRes->ai_next; 
      } 
     } 

     freeaddrinfo (res); 
    } 

    return foundAddress; 
} 

你能給我諮詢嗎?我真的好像被困在這裏,乳清是那些(低)數量的用戶在這段代碼中看到的問題?我需要額外的支票嗎?

我真的可以使用你的提示/諮詢。

重要提示:受影響的用戶表示只有在網絡丟失時纔會發生。但我不能接受一個丟失的網絡連接可能會造成上述問題?

編輯: 我做了泄漏測試;很長一段時間,通過僞造沒有DNS結果(如果(retval!= 0)),但沒有內存泄漏在我的Mac上。

+1

什麼操作系統版本?崩潰堆棧總是一樣的? – 2010-10-04 17:08:15

+0

到目前爲止只有一個崩潰;但如果有一個會有更多的:)它是在10.6.4。 – 2010-10-04 17:31:36

+0

你叫*你的類* CFNetworkStream?餿主意;如果Apple增加了這樣一個類,那麼兩者會發生衝突,您的應用可能會中斷。使用你自己的前綴,不要複製任何Apple的。 – 2010-10-04 21:02:20

回答

0

好的,我已經通過確保getaddrinfo不會被太多線程同時調用太多來修復它。還爲結果添加了本地緩存(在應用程序dns緩存中)。

我認爲真正的問題是,當用戶出現連接問題時,許多連接線程可能會過多地氾濫getaddrinfo,直到崩潰。

0

那麼,一方面,測試if (hostNameC!=NULL)沒有完成任何事情:hostnameC是一個數組(不是指針),它永遠不會== NULL。那麼,您是在處理hostname == NULL還是hostname爲零長度的情況?

您不檢查-getCString: maxLength: encoding:的返回值;如果該呼叫失敗,您將傳遞未初始化的垃圾到getaddrinfo

+0

HostNameC!= NULL你就在那裏,但不是一個破壞者。在我的一個測試中,我使用了malloc。該代碼可以被刪除。用戶報告它工作正常(很好的主機名,這是一個偏好填充)很長一段時間後,它會中斷。但我在那裏添加更多的測試代碼!非常感謝。 – 2010-10-04 17:24:35