2012-05-03 53 views
1

我想通過一系列的檢查/插入到MySQL 5.5分貝,但我有SIGSEGV錯誤頻繁但間歇性的問題。在執行許多查詢的過程中,SELECT語句運行良好。但是,(在程序正常退出有時數千的檢查,有時1或2,有時甚至根本沒有和)後的一段可變量或執行的查詢號碼,我莫名其妙地得到了段錯誤...MySQL段錯誤,間歇

Program received signal SIGSEGV, Segmentation fault. 
0x100188a8 in mysql_send_query() from K:\Programming\C\Test\libmysql.dll 
(gdb) bt full 
#0 0x100188a8 in mysql_send_query() from K:\Programming\C\Test\libmysql.dll 
No symbol table info available. 
#1 0x100188e5 in mysql_real_query() from K:\Programming\C\Test\libmysql.dll 
No symbol table info available. 
#2 0x00000000 in ??() 
No symbol table info available. 
(gdb) 

這是我的重降低代碼:

int main() { 

    for (int i = 0; i < 5000; i++) { 
     int iNewX = GenerateRandomInt(1, 50); 
     int iNewY = GenerateRandomInt(1, 50); 
     std::string str = "SELECT * FROM Resources WHERE XPOS = "; 
     str = str + 
      StatToString(iNewX) + " AND YPOS = " + 
      StatToString(iNewY) + ";"; 

     const char * Query = str.c_str(); 

     MYSQL *connect; 
     connect=mysql_init(NULL); 
     connect=mysql_real_connect(connect,SERVER,USER,PASSWORD,DATABASE,0,NULL,0); 
      // Print SQL statment for debugging only... 
      // This appears to always be good, even in the case of the segfault. 
     std::cout << Query << std::endl; 
     if (mysql_query(connect, Query)) { 
       // Supposed to log an error; I don't get this far... 
       // This does work when I intentionally break the statement. 
          std::cout << printf("Failed to SELECT, Error: %s", mysql_error(connect)); 
       std::cout << printf("Query: %s", Query) << std::endl; 
       mysql_close(connect); 
      return 0; 
     } 
     mysql_close(connect); 

    } 

    return 1; 

} 

我已經在真正符合我所會在這裏(雖然有很多的MySQL /段錯誤相關的論壇/ Q + A的話題的情況下,在網上搜索不成功/線程)。由於這似乎是在.dll本身發生的,我該如何解決這個問題?

任何人都可以解釋爲什麼這個問題似乎來來去去?

我還沒有嘗試重新安裝MySQL,因爲這可能會是一個非常令人頭疼的問題,我寧願避免。如果我必須,那麼我必須。

如果我錯過了我的問題或任何相關代碼的任何細節,請讓我知道,我會補充。


以下Christian.K's意見後,我能看到,這是錯誤23(由mysql_error(connect)返回)connect=mysql_init(NULL)之後。

這引出了我的一些資源,最清楚的是,this one。這就是說,在Windows中工作時這是一個知之甚少的問題,對此我也無能爲力。

+0

幾件事情:檢查'mysql_init'的返回值,尤其是'mysql_real_connect'。如果出現錯誤,稍後返回「NULL」。我不是MySQL的專家,但也許'mysql_query'不喜歡傳遞一個空指針作爲第一個參數。另外,'cout << printf'有點奇怪。你真的想首先打印消息(printf),然後輸出它的字符數(這是printf的返回值) - 儘管這不應該是'SIGSEGV'。 –

+0

@ Christian.K其實,這個錯誤陷阱是從一個在線教程中挑選出來的,但是感謝這些信息。你會在這些行後面提示「if(connect!= NULL){...}」嗎?即便如此,我仍然不明白爲什麼它在我遇到任何問題之前多次工作。 – Gaffi

+0

是的,這是我的建議。這可能是因爲連接有時會失敗(無論什麼原因,也許'mysql_error()'在這裏也有幫助),然後'NULL'被返回並傳遞給'mysql_query'。但是,處理這個錯誤是一種很好的風格,可能有助於診斷這裏的根本原因。除此之外,我沒有MySQL的知識;-) –

回答

2

您可以通過不爲每個循環迭代打開連接(無論如何都存在問題)來解決打開的文件限制(錯誤23),而是爲所有循環迭代使用一個連接。

與我有關錯誤處理意見

在一起,怪cout << printf用你最終的東西是這樣的:

int main() { 

    MYSQL *connect; 
    connect=mysql_init(NULL); 

    if (connect == NULL) 
    { 
     printf("Insufficient memory to initialize.\n"); 
     return 1; 
    } 

    connect=mysql_real_connect(connect,SERVER,USER,PASSWORD,DATABASE,0,NULL,0); 

    if (connect == NULL) 
    { 
     printf("Could not connect: %s\n", mysql_error(connect); 
     return 1; 
    } 

    for (int i = 0; i < 5000; i++) { 
     int iNewX = GenerateRandomInt(1, 50); 
     int iNewY = GenerateRandomInt(1, 50); 
     std::string str = "SELECT * FROM Resources WHERE XPOS = "; 
     str = str + 
      StatToString(iNewX) + " AND YPOS = " + 
      StatToString(iNewY) + ";"; 

     const char * Query = str.c_str(); 

     if (mysql_query(connect, Query)) { 
      // Supposed to log an error; I don't get this far... 
      // This does work when I intentionally break the statement. 
      printf("Failed to SELECT, Error: %s", mysql_error(connect)); 
      printf("Query: %s", Query); 
      mysql_close(connect); 

      return 1; 
     } 
    } 

    mysql_close(connect); 
    return 0; 
} 

請注意,我也改變返回值。按照慣例main()應該返回0成功和其他東西(主要是1)否則。

+0

再次感謝您的指導。再次,這是嚴重縮減的代碼,並且一些代碼實際上駐留在另一個類/另一個源文件中。那麼我會認爲我必須將'connect'作爲參數傳遞給這些函數,對嗎?另外,我相信我會在某個地方閱讀,希望在不再需要時立即關閉連接。我的代碼更多的是一個工作示例,但是一旦完全展開,查詢將以一系列的方式運行,然後等待一段時間,然後重新開始。我應該讓連接一直開着嗎? – Gaffi

+0

我將使用相同的連接來處理邏輯上屬於一起的(多個)語句,即使這意味着保持連接打開時間更長。你應該在谷歌/關於「工作單元」模式的SO問題上找出更多。一般來說,需要更多有關您的應用程序的目的和工作的信息才能給出合理的建議。 –

+0

爲了記錄,這(迄今)的作品非常漂亮。我正在使用一個類來實際處理和SQL相關的函數,並且已將連接/關閉調用添加到ctor/dtor。這樣做,我已經能夠設置比原始程序甚至要求更長的測試運行時間。謝謝。 – Gaffi