jst*_*rdo 3 c++ linux profiling valgrind
我正在开发一个 C++ 程序,完成后,我想检查内存泄漏,但我发现 valgrind 出现了一个奇怪的错误:
\n\n ==9106== Invalid free() / delete / delete[] / realloc()\n ==9106== at 0x4006C58: free (vg_replace_malloc.c:427)\n ==9106== by 0x42EB637D: free_mem (in /lib/libc-2.5.so)\n ==9106== by 0x42EB5F16: __libc_freeres (in /lib/libc-2.5.so)\n ==9106== by 0x4002451: _vgnU_freeres (vg_preloaded.c:61)\n ==9106== by 0x42E38EA3: _Exit (in /lib/libc-2.5.so)\n ==9106== by 0x42DC0DF3: (below main) (in /lib/libc-2.5.so)\n ==9106== Address 0x403f818 is not stack\'d, malloc\'d or (recently) free\'d\nRun Code Online (Sandbox Code Playgroud)\n\n由于它没有告诉任何有关无效删除所在的行号的信息,因此我不得不使用注释块的方法。
\n\n令人惊讶的是,直到我注释了所有代码,错误仍然出现。
\n\n我终于有了这段代码:
\n\nint main(int argc, char** argv) {\n /* ... all other code */\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这里发生了什么?流浪虫?那么,我可以安全地忽略该错误吗?
\n\n我以这种方式运行 valgrind 3.7.0(在 Linux 下):
\n\n$ valgrind --track-origins=yes --leak-check=full --show-reachable=yes ./bioweds_client\nRun Code Online (Sandbox Code Playgroud)\n\n编辑:
\n\n这是整个代码:
\n\n/* \n * File: main.cpp\n * Author: jstuardo\n *\n * Created on March 22, 2013, 7:32 PM\n */\n\n\n#include <cstdlib>\n#include <iostream>\n/*\n#include <string>\n#include <map>\n\n#include "Settings.h"\n#include "FComm.h"\n#include "Log.h"\n#include "Helper.h"\n\nusing namespace std;\n\nstatic string get_optional_parameter(std::map<string, string> parameters, string key) {\n if (parameters.count(key) == 0)\n return "";\n else\n return parameters[key];\n}\n\nstatic bool show_usage(std::string name) {\n std::cerr << "Uso: " << name << " OPCIONES\\n\\n"\n << "Las opciones posibles son:\\n"\n << "\\t--command COMANDO\\tComando que se les env\xc3\xada a los equipos biom\xc3\xa9tricos\\n"\n << "\\t--ip IP\\t\\t\\tEspecifica la direcci\xc3\xb3n IP de un equipo\\n"\n << "\\t--staff STAFF\\t\\tEspecifica el ID de un funcionario\\n"\n << "\\t--date_from FECHA\\tEspecifica la fecha de inicio de una consulta a la base de datos\\n"\n << "\\t--date_to FECHA\\t\\tEspecifica la fecha de t\xc3\xa9rmino de una consulta a la base de datos\\n"\n << "\\t--fingers DEDOS\\t\\tEspecifica los dedos de ambas manos para las cuales realizar una oepraci\xc3\xb3n\\n"\n << "\\t--verbose\\t\\tMuestra por consola la operaci\xc3\xb3n de la aplicaci\xc3\xb3n\\n"\n << "\\t--retries INTENTOS\\t\\tCantidad de intentos que debe realizar para la conexi\xc3\xb3n en caso de error de comunicaci\xc3\xb3n\\n"\n << "\\t--delay RETARDO\\t\\tCantidad de milisegundos a esperar luego que se env\xc3\xada el comando\\n"\n << "\\t--thread\\t\\tEnv\xc3\xada los comandos a los equipos mediante threads\\n"\n << "\\t--source SOURCE \\t\\tEspecifica archivo existente en el equipo indicado por IP\\n"\n << "\\t--target TARGET \\t\\tEspecifica archivo a crear en el PC\\n\\n"\n << "Los comandos posibles son:\\n"\n << "\\tcheck\\tVerifica la comunicaci\xc3\xb3n con el equipo dado por el par\xc3\xa1metro --ip\\n"\n << "\\tbroadcast\\tTransmite todos los archivos existentes en la carpeta \\"" << FComm::SHARE_FOLDER << "\\" a todos los equipos configurados, excepto al indicado por el par\xc3\xa1meto --ip\\n"\n << "\\tset_time\\tSincroniza la fecha y hora de todos los equipos configurados con la fecha y hora del PC\\n"\n << "\\tget_fingerprints\\tObtiene los archivos de huellas desde el equipo indicado por el par\xc3\xa1metro --ip del funcionario indicado por el par\xc3\xa1metro --staff\\n"\n << "\\tdelete_fingerprints\\tBorra las huellas de todos los equipos configurados. Las huellas se indican con el par\xc3\xa1metro --fingers como sigue: 0:1:2:3:4:5:6:7:8:9 (para todos o algunos de los dedos\\n"\n << "\\tget_logs\\tObtiene las marcaciones existentes en los equipos configurados (archivos wdjl y los almacena en la carpeta \\"" << FComm::WDJL_FOLDER << "\\")\\n"\n << "\\tprocess_logs\\tProcesa todos los registros existentes en la carpeta \\"" << FComm::WDJL_FOLDER << "\\"\\n"\n << "\\tget_archives\\tObtiene el archivo de funcionarios y los almacena en la carpeta \\"" << FComm::SHARE_FOLDER << "\\")\\n"\n << "\\tget_photos\\tObtiene las fotos de las marcas que a\xc3\xban no tienen foto de todos los equipos configurados. Si se especifican fechas, se traen solo las fotos de las marcas de ese intervalo.\\n"\n << "\\tget_one_photo\\tObtiene una \xc3\xbanica foto desde el equipo indicado por IP." << endl;\n\n return true;\n}\n*/\n\n/*\n * \n */\nint main(int argc, char** argv) {\n std::cout << "all commented" << std::endl;\n return 0;\n /*\n bool verbose = false;\n bool multithread = false;\n int retries = 0;\n int delay = 0;\n std::string command;\n std::map<string, string> parameters;\n\n // Lee los par\xc3\xa1metros de la l\xc3\xadnea de comandos\n for (int i = 1; i < argc; ++i) {\n if (string(argv[i]) == "--command") {\n if (i + 1 < argc)\n command = argv[++i];\n } else if (string(argv[i]) == "--ip") {\n if (i + 1 < argc)\n parameters["ip"] = argv[++i];\n } else if (string(argv[i]) == "--staff") {\n if (i + 1 < argc)\n parameters["staff"] = argv[++i];\n } else if (string(argv[i]) == "--date_from") {\n if (i + 1 < argc)\n parameters["date_from"] = argv[++i];\n } else if (string(argv[i]) == "--date_to") {\n if (i + 1 < argc)\n parameters["date_to"] = argv[++i];\n } else if (string(argv[i]) == "--fingers") {\n if (i + 1 < argc)\n parameters["fingers"] = argv[++i];\n } else if (string(argv[i]) == "--retries") {\n if (i + 1 < argc)\n retries = atoi(argv[++i]);\n } else if (string(argv[i]) == "--delay") {\n if (i + 1 < argc)\n delay = atoi(argv[++i]);\n } else if (string(argv[i]) == "--verbose") {\n verbose = true;\n } else if (string(argv[i]) == "--thread") {\n multithread = true;\n } else if (string(argv[i]) == "--source") {\n if (i + 1 < argc)\n parameters["source"] = argv[++i];\n } else if (string(argv[i]) == "--target") {\n if (i + 1 < argc)\n parameters["target"] = argv[++i];\n }\n }\n\n string executable = argv[0];\n executable = executable.substr(executable.find_last_of("/") + 1);\n\n bool salida = false;\n\n if (command == "")\n salida |= show_usage(executable);\n else if (command == "get_fingerprints" && (parameters.count("ip") == 0 || parameters.count("staff") == 0))\n salida |= show_usage(executable);\n else if (command == "delete_fingerprints" && parameters.count("fingers") == 0)\n salida |= show_usage(executable);\n else if (command == "get_bulk_photos" && parameters.count("ip") == 0)\n salida |= show_usage(executable);\n else if (command == "delete_bulk_photos" && parameters.count("ip") == 0)\n salida |= show_usage(executable);\n else if (command == "get_archives" && parameters.count("ip") == 0)\n salida |= show_usage(executable); \n else if (command == "get_one_photo" && parameters.count("ip") == 0 && parameters.count("source") == 0 && parameters.count("target") == 0)\n salida |= show_usage(executable);\n\n if (command != "check" && command != "broadcast" && command != "set_time" && command != "get_fingerprints"\n && command != "delete_fingerprints" && command != "get_logs" && command != "process_logs"\n && command != "get_photos" && command != "get_bulk_photos" && command != "delete_bulk_photos" \n && command != "get_one_photo" && command != "get_archives" && command != "decrypt_file")\n salida |= show_usage(executable);\n\n if (salida)\n return EXIT_FAILURE;\n\n Helper::CheckFolder(FComm::LOG_FOLDER);\n Log log(FComm::LOG_FOLDER + "common.log");\n\n if (verbose) {\n cout << "Ejecutando comando [" << command << "] con los par\xc3\xa1metros:" << endl;\n for (map<string, string>::iterator it = parameters.begin(); it != parameters.end(); it++)\n cout << "\\t" << it->first << " = " << it->second << endl;\n\n cout << "\\tReintentos = " << retries << endl;\n\n cout << "\\tRetardo = " << delay << " milisegundos" << endl;\n\n if (multithread) cout << "\\tMultithread" << endl;\n else cout << "\\tSecuencial" << endl;\n }\n\n log.Write("Ejecutando comando [" + command + "] con los par\xc3\xa1metros:");\n for (map<string, string>::iterator it = parameters.begin(); it != parameters.end(); it++)\n log.Write("\\t" + it->first + " = " + it->second);\n\n if (multithread) log.Write("\\tMultithread");\n else log.Write("\\tSecuencial");\n\n Settings settings;\n FComm fcomm(settings, retries, delay, verbose, multithread);\n\n bool exito = false;\n if (command == "check")\n exito = fcomm.Check(get_optional_parameter(parameters, "ip"));\n else if (command == "broadcast")\n exito = fcomm.Broadcast(get_optional_parameter(parameters, "ip"));\n else if (command == "set_time")\n exito = fcomm.SetTime(get_optional_parameter(parameters, "ip"));\n else if (command == "get_fingerprints")\n exito = fcomm.GetFingerprints(parameters["staff"], parameters["ip"]);\n else if (command == "delete_fingerprints")\n exito = fcomm.DeleteFingerprints(parameters["staff"], get_optional_parameter(parameters, "ip"), get_optional_parameter(parameters, "fingers"));\n else if (command == "get_logs")\n exito = fcomm.GetLogs(get_optional_parameter(parameters, "ip"));\n else if (command == "process_logs")\n exito = fcomm.ProcessLogs();\n else if (command == "get_archives")\n exito = fcomm.GetArchives(get_optional_parameter(parameters, "ip")); \n else if (command == "get_photos")\n exito = fcomm.GetPhotos(get_optional_parameter(parameters, "ip"), get_optional_parameter(parameters, "date_from"), get_optional_parameter(parameters, "date_to"));\n else if (command == "get_one_photo")\n exito = fcomm.GetOnePhoto(parameters["ip"], parameters["source"], parameters["target"]);\n else if (command == "decrypt_file")\n exito = fcomm.DecryptFile(parameters["source"]);\n\n log.Write("Saliendo en forma exitosa.");\n\n return exito ? EXIT_SUCCESS : EXIT_FAILURE;\n */\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这是整个 valgrind 输出:
\n\n[root@Linux v2]# valgrind --track-origins=yes --leak-check=full --show-reachable=yes ./bioweds_client\n==10441== Memcheck, a memory error detector\n==10441== Copyright (C) 2002-2011, and GNU GPL\'d, by Julian Seward et al.\n==10441== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info\n==10441== Command: ./bioweds_client\n==10441== \nall commented\n==10441== Invalid free() / delete / delete[] / realloc()\n==10441== at 0x4006C58: free (vg_replace_malloc.c:427)\n==10441== by 0x42EB637D: free_mem (in /lib/libc-2.5.so)\n==10441== by 0x42EB5F16: __libc_freeres (in /lib/libc-2.5.so)\n==10441== by 0x4002451: _vgnU_freeres (vg_preloaded.c:61)\n==10441== by 0x42E38EA3: _Exit (in /lib/libc-2.5.so)\n==10441== by 0x42DC0DF3: (below main) (in /lib/libc-2.5.so)\n==10441== Address 0x403f818 is not stack\'d, malloc\'d or (recently) free\'d\n==10441== \n==10441== \n==10441== HEAP SUMMARY:\n==10441== in use at exit: 0 bytes in 0 blocks\n==10441== total heap usage: 8 allocs, 9 frees, 186 bytes allocated\n==10441== \n==10441== All heap blocks were freed -- no leaks are possible\n==10441== \n==10441== For counts of detected and suppressed errors, rerun with: -v\n==10441== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 33 from 8)\n[root@Linux v2]# \nRun Code Online (Sandbox Code Playgroud)\n\n提前致谢,
\n\n海梅
\n这是 libc 中的一个错误,现已修复。
您可以忽略此错误,或使用 valgrind 选项--run-libc-freeres=no来避免它。
__libc_freeres在退出时调用以释放资源;该错误是从单独的池分配的内存被返回到 libc malloc/free 区域。
有关详细信息,请参阅http://valgrind.org/docs/manual/faq.html#faq.exit_errors 和https://bugzilla.redhat.com/show_bug.cgi?id=629976