2013-05-18 50 views
3

我開發一個C++程序,完成後,我想檢查內存泄漏,但我已經找到了Valgrind的一個奇怪的錯誤:使用valgrind時出現奇怪的錯誤?一個錯誤可能?

==9106== Invalid free()/delete/delete[]/realloc() 
    ==9106== at 0x4006C58: free (vg_replace_malloc.c:427) 
    ==9106== by 0x42EB637D: free_mem (in /lib/libc-2.5.so) 
    ==9106== by 0x42EB5F16: __libc_freeres (in /lib/libc-2.5.so) 
    ==9106== by 0x4002451: _vgnU_freeres (vg_preloaded.c:61) 
    ==9106== by 0x42E38EA3: _Exit (in /lib/libc-2.5.so) 
    ==9106== by 0x42DC0DF3: (below main) (in /lib/libc-2.5.so) 
    ==9106== Address 0x403f818 is not stack'd, malloc'd or (recently) free'd 

因爲它沒有告訴行號的任何地方無效刪除在場的時候,我不得不使用評論封鎖的方法。

令人驚訝的是,我得到了直到我評論所有代碼的觀點,並且錯誤仍然出現。

我終於驗證碼:

int main(int argc, char** argv) { 
    /* ... all other code */ 
    return 0; 
} 

這到底是怎麼回事?一個迷路的臭蟲?那麼,我可以放心地忽略那個錯誤嗎?

我運行的valgrind 3.7.0這種方式(在Linux下):

$ valgrind --track-origins=yes --leak-check=full --show-reachable=yes ./bioweds_client 

編輯:

這是整個代碼:

/* 
* File: main.cpp 
* Author: jstuardo 
* 
* Created on March 22, 2013, 7:32 PM 
*/ 


#include <cstdlib> 
#include <iostream> 
/* 
#include <string> 
#include <map> 

#include "Settings.h" 
#include "FComm.h" 
#include "Log.h" 
#include "Helper.h" 

using namespace std; 

static string get_optional_parameter(std::map<string, string> parameters, string key) { 
    if (parameters.count(key) == 0) 
     return ""; 
    else 
     return parameters[key]; 
} 

static bool show_usage(std::string name) { 
    std::cerr << "Uso: " << name << " OPCIONES\n\n" 
      << "Las opciones posibles son:\n" 
      << "\t--command COMANDO\tComando que se les envía a los equipos biométricos\n" 
      << "\t--ip IP\t\t\tEspecifica la dirección IP de un equipo\n" 
      << "\t--staff STAFF\t\tEspecifica el ID de un funcionario\n" 
      << "\t--date_from FECHA\tEspecifica la fecha de inicio de una consulta a la base de datos\n" 
      << "\t--date_to FECHA\t\tEspecifica la fecha de término de una consulta a la base de datos\n" 
      << "\t--fingers DEDOS\t\tEspecifica los dedos de ambas manos para las cuales realizar una oepración\n" 
      << "\t--verbose\t\tMuestra por consola la operación de la aplicación\n" 
      << "\t--retries INTENTOS\t\tCantidad de intentos que debe realizar para la conexión en caso de error de comunicación\n" 
      << "\t--delay RETARDO\t\tCantidad de milisegundos a esperar luego que se envía el comando\n" 
      << "\t--thread\t\tEnvía los comandos a los equipos mediante threads\n" 
      << "\t--source SOURCE \t\tEspecifica archivo existente en el equipo indicado por IP\n" 
      << "\t--target TARGET \t\tEspecifica archivo a crear en el PC\n\n" 
      << "Los comandos posibles son:\n" 
      << "\tcheck\tVerifica la comunicación con el equipo dado por el parámetro --ip\n" 
      << "\tbroadcast\tTransmite todos los archivos existentes en la carpeta \"" << FComm::SHARE_FOLDER << "\" a todos los equipos configurados, excepto al indicado por el parámeto --ip\n" 
      << "\tset_time\tSincroniza la fecha y hora de todos los equipos configurados con la fecha y hora del PC\n" 
      << "\tget_fingerprints\tObtiene los archivos de huellas desde el equipo indicado por el parámetro --ip del funcionario indicado por el parámetro --staff\n" 
      << "\tdelete_fingerprints\tBorra las huellas de todos los equipos configurados. Las huellas se indican con el parámetro --fingers como sigue: 0:1:2:3:4:5:6:7:8:9 (para todos o algunos de los dedos\n" 
      << "\tget_logs\tObtiene las marcaciones existentes en los equipos configurados (archivos wdjl y los almacena en la carpeta \"" << FComm::WDJL_FOLDER << "\")\n" 
      << "\tprocess_logs\tProcesa todos los registros existentes en la carpeta \"" << FComm::WDJL_FOLDER << "\"\n" 
      << "\tget_archives\tObtiene el archivo de funcionarios y los almacena en la carpeta \"" << FComm::SHARE_FOLDER << "\")\n" 
      << "\tget_photos\tObtiene las fotos de las marcas que aún no tienen foto de todos los equipos configurados. Si se especifican fechas, se traen solo las fotos de las marcas de ese intervalo.\n" 
      << "\tget_one_photo\tObtiene una única foto desde el equipo indicado por IP." << endl; 

    return true; 
} 
*/ 

/* 
* 
*/ 
int main(int argc, char** argv) { 
    std::cout << "all commented" << std::endl; 
    return 0; 
    /* 
    bool verbose = false; 
    bool multithread = false; 
    int retries = 0; 
    int delay = 0; 
    std::string command; 
    std::map<string, string> parameters; 

    // Lee los parámetros de la línea de comandos 
    for (int i = 1; i < argc; ++i) { 
     if (string(argv[i]) == "--command") { 
      if (i + 1 < argc) 
       command = argv[++i]; 
     } else if (string(argv[i]) == "--ip") { 
      if (i + 1 < argc) 
       parameters["ip"] = argv[++i]; 
     } else if (string(argv[i]) == "--staff") { 
      if (i + 1 < argc) 
       parameters["staff"] = argv[++i]; 
     } else if (string(argv[i]) == "--date_from") { 
      if (i + 1 < argc) 
       parameters["date_from"] = argv[++i]; 
     } else if (string(argv[i]) == "--date_to") { 
      if (i + 1 < argc) 
       parameters["date_to"] = argv[++i]; 
     } else if (string(argv[i]) == "--fingers") { 
      if (i + 1 < argc) 
       parameters["fingers"] = argv[++i]; 
     } else if (string(argv[i]) == "--retries") { 
      if (i + 1 < argc) 
       retries = atoi(argv[++i]); 
     } else if (string(argv[i]) == "--delay") { 
      if (i + 1 < argc) 
       delay = atoi(argv[++i]); 
     } else if (string(argv[i]) == "--verbose") { 
      verbose = true; 
     } else if (string(argv[i]) == "--thread") { 
      multithread = true; 
     } else if (string(argv[i]) == "--source") { 
      if (i + 1 < argc) 
       parameters["source"] = argv[++i]; 
     } else if (string(argv[i]) == "--target") { 
      if (i + 1 < argc) 
       parameters["target"] = argv[++i]; 
     } 
    } 

    string executable = argv[0]; 
    executable = executable.substr(executable.find_last_of("/") + 1); 

    bool salida = false; 

    if (command == "") 
     salida |= show_usage(executable); 
    else if (command == "get_fingerprints" && (parameters.count("ip") == 0 || parameters.count("staff") == 0)) 
     salida |= show_usage(executable); 
    else if (command == "delete_fingerprints" && parameters.count("fingers") == 0) 
     salida |= show_usage(executable); 
    else if (command == "get_bulk_photos" && parameters.count("ip") == 0) 
     salida |= show_usage(executable); 
    else if (command == "delete_bulk_photos" && parameters.count("ip") == 0) 
     salida |= show_usage(executable); 
    else if (command == "get_archives" && parameters.count("ip") == 0) 
     salida |= show_usage(executable);  
    else if (command == "get_one_photo" && parameters.count("ip") == 0 && parameters.count("source") == 0 && parameters.count("target") == 0) 
     salida |= show_usage(executable); 

    if (command != "check" && command != "broadcast" && command != "set_time" && command != "get_fingerprints" 
      && command != "delete_fingerprints" && command != "get_logs" && command != "process_logs" 
      && command != "get_photos" && command != "get_bulk_photos" && command != "delete_bulk_photos" 
      && command != "get_one_photo" && command != "get_archives" && command != "decrypt_file") 
     salida |= show_usage(executable); 

    if (salida) 
     return EXIT_FAILURE; 

    Helper::CheckFolder(FComm::LOG_FOLDER); 
    Log log(FComm::LOG_FOLDER + "common.log"); 

    if (verbose) { 
     cout << "Ejecutando comando [" << command << "] con los parámetros:" << endl; 
     for (map<string, string>::iterator it = parameters.begin(); it != parameters.end(); it++) 
      cout << "\t" << it->first << " = " << it->second << endl; 

     cout << "\tReintentos = " << retries << endl; 

     cout << "\tRetardo = " << delay << " milisegundos" << endl; 

     if (multithread) cout << "\tMultithread" << endl; 
     else cout << "\tSecuencial" << endl; 
    } 

    log.Write("Ejecutando comando [" + command + "] con los parámetros:"); 
    for (map<string, string>::iterator it = parameters.begin(); it != parameters.end(); it++) 
     log.Write("\t" + it->first + " = " + it->second); 

    if (multithread) log.Write("\tMultithread"); 
    else log.Write("\tSecuencial"); 

    Settings settings; 
    FComm fcomm(settings, retries, delay, verbose, multithread); 

    bool exito = false; 
    if (command == "check") 
     exito = fcomm.Check(get_optional_parameter(parameters, "ip")); 
    else if (command == "broadcast") 
     exito = fcomm.Broadcast(get_optional_parameter(parameters, "ip")); 
    else if (command == "set_time") 
     exito = fcomm.SetTime(get_optional_parameter(parameters, "ip")); 
    else if (command == "get_fingerprints") 
     exito = fcomm.GetFingerprints(parameters["staff"], parameters["ip"]); 
    else if (command == "delete_fingerprints") 
     exito = fcomm.DeleteFingerprints(parameters["staff"], get_optional_parameter(parameters, "ip"), get_optional_parameter(parameters, "fingers")); 
    else if (command == "get_logs") 
     exito = fcomm.GetLogs(get_optional_parameter(parameters, "ip")); 
    else if (command == "process_logs") 
     exito = fcomm.ProcessLogs(); 
    else if (command == "get_archives") 
     exito = fcomm.GetArchives(get_optional_parameter(parameters, "ip"));  
    else if (command == "get_photos") 
     exito = fcomm.GetPhotos(get_optional_parameter(parameters, "ip"), get_optional_parameter(parameters, "date_from"), get_optional_parameter(parameters, "date_to")); 
    else if (command == "get_one_photo") 
     exito = fcomm.GetOnePhoto(parameters["ip"], parameters["source"], parameters["target"]); 
    else if (command == "decrypt_file") 
     exito = fcomm.DecryptFile(parameters["source"]); 

    log.Write("Saliendo en forma exitosa."); 

    return exito ? EXIT_SUCCESS : EXIT_FAILURE; 
    */ 
} 

這是整個的valgrind輸出:

[[email protected] v2]# valgrind --track-origins=yes --leak-check=full --show-reachable=yes ./bioweds_client 
==10441== Memcheck, a memory error detector 
==10441== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al. 
==10441== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info 
==10441== Command: ./bioweds_client 
==10441== 
all commented 
==10441== Invalid free()/delete/delete[]/realloc() 
==10441== at 0x4006C58: free (vg_replace_malloc.c:427) 
==10441== by 0x42EB637D: free_mem (in /lib/libc-2.5.so) 
==10441== by 0x42EB5F16: __libc_freeres (in /lib/libc-2.5.so) 
==10441== by 0x4002451: _vgnU_freeres (vg_preloaded.c:61) 
==10441== by 0x42E38EA3: _Exit (in /lib/libc-2.5.so) 
==10441== by 0x42DC0DF3: (below main) (in /lib/libc-2.5.so) 
==10441== Address 0x403f818 is not stack'd, malloc'd or (recently) free'd 
==10441== 
==10441== 
==10441== HEAP SUMMARY: 
==10441==  in use at exit: 0 bytes in 0 blocks 
==10441== total heap usage: 8 allocs, 9 frees, 186 bytes allocated 
==10441== 
==10441== All heap blocks were freed -- no leaks are possible 
==10441== 
==10441== For counts of detected and suppressed errors, rerun with: -v 
==10441== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 33 from 8) 
[[email protected] v2]# 

由於提前,

海梅

+0

我很懷疑它在Valgrind的一個bug。我在valgrind的確切版本上嘗試了確切的代碼,並沒有得到一個錯誤。你確定一切都真的被評論了嗎?你的編譯命令是什麼? – BraveNewCurrency

+0

如果使用調試符號編譯,Valgrind應該告訴你行號。 –

+0

我添加了整個代碼和整個valgrind輸出。請檢查。另外,我正在使用調試版本。 – jstuardo

回答

0

由於_Exit是堆棧跟蹤,無效的自由可能是在析構函數發生了一些全局或靜態變量。它可能不在你的源文件中,但是在你已經包含的類中,甚至是你連接的庫中。

+0

唯一包含的庫是標準庫,正如您在源代碼中看到的那樣,我鏈接的非標準庫是PostgreSQL庫(它們是函數,而不是類),但由於我評論了所有代碼,因此不需要調用外部函數被調用。問候, – jstuardo

相關問題