throw () с clang ++ показывает возможную утечку памяти - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть кусок кода, который при компиляции с 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 распределения. Который я предполагаю относить к третьему объекту, но как я могу гарантировать, что он очищен (или не выделен сам)?

Возможно, то же самое может помочь мне исправить мой исходный код.

...