У меня есть кусок кода, который при компиляции с g ++ не показывает утечек памяти. Принимая во внимание, что то же самое при компиляции с использованием clang ++ показывает возможную утечку памяти.
Вот трассировка,
==7115==
==7115== HEAP SUMMARY:
==7115== in use at exit: 16 bytes in 1 blocks
==7115== total heap usage: 2,324 allocs, 2,323 frees, 2,166,060 bytes allocated
==7115==
==7115== 16 bytes in 1 blocks are still reachable in loss record 1 of 1
==7115== at 0x4C2BFB9: calloc (vg_replace_malloc.c:762)
==7115== by 0x4129830: __cxxabiv1::__calloc_with_fallback(unsigned long, unsigned long) (in /opt/xxx/lib64/libc++abi.so.1)
==7115== by 0x4128946: __cxa_get_globals (in /opt/xxx/lib64/libc++abi.so.1)
==7115== by 0x412B287: __cxa_throw (in /opt/xxx/lib64/libc++abi.so.1)
==7115== by 0x4E712AE: Lib::GenCmd::RaiseException(Status, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) (LibBase.cpp:291)
==7115==
==7115== LEAK SUMMARY:
==7115== definitely lost: 0 bytes in 0 blocks
==7115== indirectly lost: 0 bytes in 0 blocks
==7115== possibly lost: 0 bytes in 0 blocks
==7115== still reachable: 16 bytes in 1 blocks
==7115== suppressed: 0 bytes in 0 blocks
==7115==
==7115== For counts of detected and suppressed errors, rerun with: -v
Что ж, невозможно поделиться фрагментом кода, но я могу сказать вам RaiseException () - это функция, в которой я вызову throw () (в строке 291) исключение. Вот фрагмент функции:
void GenCmd::RaiseException(Status status, std::string AdditionalMsg) throw(Status) {
s_last_error = GetStatusString(status);
if (false == AdditionalMsg.empty()) {
s_last_error = s_last_error + AdditionalMsg;
}
throw(status);
}
Состояние - это структура, определенная как показано ниже (вместе с конструкторами по умолчанию и параметризацией и копированием)
typedef struct _Status {
const u64_t m_status : 8;
const u64_t ReservedByte1 : 8;
const u64_t m_action : 8;
const u64_t ReservedByte3 : 5;
const u64_t m_testbit1 : 1;
const u64_t m_testbit2 : 1;
const u64_t m_cmd_failure : 1;
const u64_t m_module_code : 4;
const u64_t m_file_code : 8;
const u64_t ReservedByte7 : 4;
const u64_t m_line_no : 16;
}Status
Тот факт, что утечки не видны при G CC, но только с Clang заставляет меня думать, что это какая-то проблема с Clang. (Я имею в виду, что с Clang это может быть libcxxabi )
Я просматривал источник для clang, & __ cxa_get_globals () - это функция, где a callo c () звонок сделан. Я еще не уверен в потоке выполнения для clang.
Любая идея или любые входные данные, которые могли бы подтвердить, что это проблема Clang, а не проблема моего кода?
Вот версия Clang, я с помощью. Код скомпилирован с C ++ 11, дополнительно с '-stdlib = libc ++,' -lc ++ ',' -lc ++ abi '.
[user~]$ clang --version
clang version 7.1.0
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
- Обновление: это исключение взято из конструктора.
Обновление Я написал другой фиктивный код, чтобы увидеть поведение с Clang, и, похоже, проблема на самом деле с Clang (libc ++ abi).
Взгляните на приведенный ниже наивный код
#include <iostream>
#include <stdexcept>
class Positive {
int m_number1;
public:
Positive() : m_number1(10) {
}
Positive(int no) {
if (no < 0) {
// throw 100;
throw std::invalid_argument("Send positive nu");
} else {
m_number1 = no;
}
}
~Positive() {
}
void print() {
std::cout<< "Value of member is: " <<m_number1 <<std::endl;
}
};
int main() {
try {
Positive p1;
p1.print();
Positive p2(100);
p2.print();
Positive p3(-10);
p3.print();
} catch(...) {
std::cout << "Some Exception occured" <<std::endl;
}
return 0;
}
Даже при выполнении приведенного выше кода, Я видел такой же результат на Valgrind. Вот вывод:
[user]$ valgrind --leak-check=full --leak-resolution=high --show-leak-kinds=all ./a.out
==119789== Memcheck, a memory error detector
==119789== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==119789== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==119789== Command: ./a.out
==119789==
Value of member is: 10
Value of member is: 100
Some Exception occured
==119789==
==119789== HEAP SUMMARY:
==119789== in use at exit: 16 bytes in 1 blocks
==119789== total heap usage: 3 allocs, 2 frees, 201 bytes allocated
==119789==
==119789== 16 bytes in 1 blocks are still reachable in loss record 1 of 1
==119789== at 0x4C2BFB9: calloc (vg_replace_malloc.c:762)
==119789== by 0x40FF830: __cxxabiv1::__calloc_with_fallback(unsigned long, unsigned long) (in /usr/local/lib/libc++abi.so.1.0)
==119789== by 0x40FE946: __cxa_get_globals (in /usr/local/lib/libc++abi.so.1.0)
==119789== by 0x4101287: __cxa_throw (in /usr/local/lib/libc++abi.so.1.0)
==119789== by 0x4014B0: Positive::Positive(int) (in /home/user/test/a.out)
==119789== by 0x4010F9: main (in /home/user/test/a.out)
==119789==
==119789== LEAK SUMMARY:
==119789== definitely lost: 0 bytes in 0 blocks
==119789== indirectly lost: 0 bytes in 0 blocks
==119789== possibly lost: 0 bytes in 0 blocks
==119789== still reachable: 16 bytes in 1 blocks
==119789== suppressed: 0 bytes in 0 blocks
==119789==
==119789== For counts of detected and suppressed errors, rerun with: -v
==119789== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[user]$
Интересно, что он показывает 3 распределения. Который я предполагаю относить к третьему объекту, но как я могу гарантировать, что он очищен (или не выделен сам)?
Возможно, то же самое может помочь мне исправить мой исходный код.