Подозрительная ошибка сегментации с использованием openmp замков - PullRequest
0 голосов
/ 01 марта 2020

Моя программа завершилась с ошибкой сегментации. Я сократил код до этого:

#include <string>
#include <omp.h>
#include <iostream>

namespace ns { // Holds three strings
    static const std::string A = "a";
    static const std::string B = "b";
    static const std::string C = "c";
}

namespace ns2 {
    // Wraps an ostream and a lock; for example, concurrent access
    // can be implemented this way
    class wrapper { 
    private:
        std::ostream &_stream;
        omp_lock_t _lock;
    public:
        wrapper(std::ostream &stream) : _stream(stream)
        {
            omp_init_lock(&_lock);
        }
        // Segmentation Fault also occurs without destructor
        ~wrapper()
        {
            omp_destroy_lock(&_lock);
        }
    };
    // Wrap stdout
    static wrapper cout(std::cout);
}

namespace ns3 {
    struct somestruct {
        const std::string _0;   
        const std::string _a;
        const std::string _b;
        const std::string _c;
        somestruct(std::string o, std::string a, std::string b, std::string c)
            : _0(o), _a(a), _b(b), _c(c) { }
    };
}

int main(int argc, char *argv[])
{   
    ns3::somestruct cont("0", ns::A, ns::B, ns::C);
    return 0;
}

Я компилирую на MacOS:

Версия системы: OS X 10.11.6 (15G22010)
Версия ядра: Darwin 15.6.0

с использованием g++-7:

g ++ - 7 (Homebrew G CC 7.5.0_1) 7.5.0
Авторское право (C ) 2017 Free Software Foundation, In c.
Это бесплатное программное обеспечение; см. источник для условий копирования. НЕТ
гарантия; даже для ПРОДАЖИ или ПРИГОДНОСТИ ДЛЯ ОСОБЕННОСТИ для -O0. Как ни странно, это происходит только на этой машине, и ни на одной из моих машин или godbolt .

Я запустил valgrind на исполняемом файле. Это вывод:

== 54305 == Memcheck, детектор ошибок памяти
== 54305 == Авторские права (C) 2002-2017, и GNU GPL'd, by Джулиан Сьюард и соавт.
== 54305 == Использование Valgrind-3.15.0 и LibVEX; для получения информации об авторских правах снова введите -h
== 54305 == Команда: ./a.out
== 54305 ==
== 54305 == Недопустимое чтение размера 1
== 54305 = = 0x100000906: void std :: __cxx11 :: basic_string, std :: allocator> :: _ M_construct (char const *, char const *, std :: forward_iterator_tag) [клон .isra.23] (basic_string.h: 338)
== 54305 == по 0x1000009E C: main (basic_string.h: 236)
== 54305 == Адрес 0x4d55545a4d55545a не стековый, mallo c d или (недавно) free'd
== 54305 ==
== 54305 == Сигнал 11 удаляется из очереди потока 0

, за которым следует бесконечный l oop из

== 54305 == Сигнал 11 удаляется из очереди потока 0

Я должен использовать kill, чтобы остановить memcheck после этого, он не реагирует на Ctrl+C. См. Также этот вопрос для аналогичного ответа от valgrind. Однако здесь, похоже, другая причина.

В данный момент я не могу использовать gdb, потому что мне нужно его кодировать (что, я думаю, невозможно только через терминал / ssh).

Еще одна интересная вещь: если я закомментирую строку ns3::somestruct cont("0", ns::A, ns::B, ns::C); вместо простой печати

Ошибка сегментации: 11

вывод программы становится

a.out (54371,0x7fff77d7d000) mallo c: *** ошибка для объекта 0x4d55545a4d55545a: освобожденный указатель не выделен
** * установить точку останова в malloc_error_break для отладки
Прерывание прерывания: 6

Я не вижу, откуда возникла ошибка сегментации. Я что-то пропустил?

Редактировать

Мне удалось заставить gdb работать. Это вывод:

[Новый поток 0x1703 процесса 55870]
Запрограммированный сигнал, полученный SIGSEGV, Ошибка сегментации.
предупреждение: `/ private / tmp / gcc@7-20200229-63593-evr5eg/gcc-7.5.0/build/x86_64-apple-darwin15.6.0/libstdc++-v3/src/.libs/compatibility-atomic-c++0x.o ': невозможно открыть для чтения символов: такого файла или каталога нет.
[сопровождается намного большим количеством подобных предупреждений]
Программа получила сигнал SIGSEGV, Ошибка сегментации.
std :: __cxx11 :: basic_string, std :: allocator> :: _ M_construct (this = 0x7fff5fbffb70, __beg = 0x4d55545a4d55545a, __end =)
(gdb) где
# st :: __cxx11 :: basic_string, std :: allocator> :: _ M_construct (this = 0x7fff5fbffb70, __beg = 0x4d55545a4d55545a, __end =)
# 1 0x0000000100000a2f в основном (argc =, us / / argv = at) gcc@7/7.5.0_1/include/c++/7.5.0/bits/basic_string.h: 236

Я до сих пор не понимаю, почему это происходит. Я недавно обновил homebrew , и с тех пор эта "ошибка", по-видимому, возникает , и с тех пор эта ошибка возникает. Любые идеи, для какой библиотеки может потребоваться обновление или подобное?

Редактировать 2

Опять же, комментирование первой строки main снимает проблему:

а. out (55934,0x7fff77d7d000) mallo c: *** ошибка для объекта 0x4d55545a4d55545a: освобожденный указатель не выделен
*** установить точку останова в malloc_error_break для отладки

Программа получила сигнал SIGABRT, Aborted ,
0x00007fff88204f06 в __pthread_kill () из /usr/lib/system/libsystem_kernel.dylib
(gdb) , где
# 0 0x00007fff88204f06 в __pthread_kill /kill из (lib) () libsystem_kernel.dylib
# 1 0x00007fff8c40d4e c в pthread_kill () из /usr/lib/system/libsystem_pthread.dylib
# 2 0x00007fff8b7f06df в abort () из / usr / lib_ system * dylib
# 3 0x00007fff88273041 в свободном доступе () из /usr/lib/system/libsystem_malloc.dylib
# 4 0x00007fff8b7f1463 в __cxa_finalize_ranges () из /usr/lib/lib/libs/libs 1132 * # 5 0x00007fff8b7f1767 в exit () из /usr/lib/system/libsystem_c.dylib
# 6 0x00007fff939de5b4 в start () из /usr/lib/system/libdyld.dylib
# 7 00000 в ?? ()

Редактировать 3

otool -L (ldd недоступно на этом аппарате, но согласно это обсуждение должно быть эквивалент) дает следующий вывод:

a.out:
/ usr / local / opt / gcc@7/lib/gcc/7/libstdc++.6.dylib (совместимость версия 7.0.0, текущая версия 7.24.0)
/ usr / local / opt / gcc@7/lib/gcc/7/libgomp.1.dylib (версия совместимости 2.0.0, текущая версия 2.0.0)
/usr/lib/libSystem.B.dylib (версия совместимости 1.0.0, текущая версия 1226.10.1)
/usr/local/lib/gcc/7/libgcc_s.1.dylib (совместимость версия 1.0.0, текущая версия 1.0.0)

Я добавлю, что происходит для gcc@9 как только он будет переустановлен, но я помню из предыдущей установки, что поведение должно быть идентичным.

Поведение идентично с g++-9. Вывод otool -L показывает варианты dylibs версии 9 за исключением /usr/lib/libSystem.B.dylib, который в данном случае идентичен.

Может ли кто-нибудь воспроизвести эту ошибку?

Редактировать 4

Я использовал otool -L в более старой версии исполняемого файла, который я скомпилировал перед обновлением homebrew. Он ссылается на

/ usr / local / opt / gcc@7/lib/gcc/7/libstdc++.6.dylib (версия совместимости 7.0.0, текущая версия 7. 23 .0)

в то время как все остальные библиотеки одинаковой версии. Кроме того, исполняемый файл g++-9 также ссылается на версию 7.24.0. Может быть, это вызывает ошибку? Как переустановить эту старую версию libstdc ++ для проверки этой гипотезы? Я заставил brew переустановить g++ версию 7.1.0, которая использует версию 7.23.0 libstdc ++. Ошибка сохраняется.

1 Ответ

0 голосов
/ 03 марта 2020

После долгих попыток я решил обновить операционную систему до macOS Mojave . Это решило проблему, после того как я brew reinstall отредактировал все . (Однако обратите внимание, что valgrind, похоже, еще не доступен для Mojave. Кроме того, я заметил больше проблем в другом программном обеспечении, таком как gnuplot, где программы не запускаются должным образом.)

Обратите внимание, что brew предупредил меня, что могут быть проблемы при попытке использовать его на старой версии macOS и что он технически больше не поддерживается. Кроме того, я обновил Xcode и clang, которые также долгое время были устаревшими.

Поэтому эта проблема, по-видимому, вызвана каким-то несоответствием версий между ОС, brew / clang и компилятором gnu .

...