Символы отладки, не включенные в gcc-скомпилированный C ++ - PullRequest
3 голосов
/ 20 июня 2019

Я строю модуль на C ++ для использования в Python. Мой процесс состоит из трех этапов: я компилирую отдельные источники C ++ в объекты, создаю библиотеку, а затем запускаю скрипт setup.py для компиляции .pyx ->. Cpp ->. Итак, обращаясь к только что созданной библиотеке.

Я знаю, что могу сделать все за один шаг с помощью Cython setup.py, и это то, что я делал раньше. Причиной разбиения его на несколько шагов является то, что я хотел бы, чтобы код C ++ развивался сам по себе, и в этом случае я бы просто использовал скомпилированную библиотеку в Cython / python.

Так что этот поток работает нормально, когда нет ошибок. Проблема в том, что я пытаюсь найти источник ошибки, поэтому я хотел бы получить символы отладки, чтобы я мог работать с gdb (который я установил в OSX 10.14, это было больно, но это работало).

У меня есть make-файл, который выполняет следующее.

Шаг 1. Компиляция отдельных исходных файлов C ++

Все файлы скомпилированы с минимальными минимальными флагами, но есть -g:

gcc -mmacosx-version-min=10.7 -stdlib=libc++ -std=c++14 -c -g -O0 -I ./csrc -o /Users/colinww/system-model/build/data_buffer.o csrc/data_buffer.cpp

Я думаю, что даже здесь есть проблема: когда я делаю nm -pa data_buffer.o, я не вижу отладочных символов. Кроме того, я получаю:

(base) cmac-2:system-model colinww$ dsymutil build/data_buffer.o
warning: no debug symbols in executable (-arch x86_64)

Шаг 2: Компилировать исходники Cython

Makefile имеет строку

cd $(CSRC_DIR) && CC=$(CC) CXX=$(CXX) python3 setup_csrc.py build_ext --build-lib $(BUILD)

Соответствующие части файла setup.py:

....
....
....
compile_args = ['-stdlib=libc++', '-std=c++14', '-O0', '-g']
link_args = ['-stdlib=libc++', '-g']
....
....
....
      Extension("circbuf",
                ["circbuf.pyx"],
                language="c++",
                libraries=["cpysim"],
                include_dirs = ['../build'],
                library_dirs=['../build'],
                extra_compile_args=compile_args,
                extra_link_args=link_args),
....
....
....
ext = cythonize(extensions,
                gdb_debug=True,
                compiler_directives={'language_level': '3'})

setup(ext_modules=ext,
      cmdclass={'build_ext': build_ext},
      include_dirs=[np.get_include()])

Когда он запускается, он генерирует кучу команд компиляции / компоновки, таких как

gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/colinww/anaconda3/include -arch x86_64 -I/Users/colinww/anaconda3/include -arch x86_64 -I. -I../build -I/Users/colinww/anaconda3/lib/python3.7/site-packages/numpy/core/include -I/Users/colinww/anaconda3/include/python3.7m -c circbuf.cpp -o build/temp.macosx-10.7-x86_64-3.7/circbuf.o -stdlib=libc++ -std=c++14 -O0 -g

и

g++ -bundle -undefined dynamic_lookup -L/Users/colinww/anaconda3/lib -arch x86_64 -L/Users/colinww/anaconda3/lib -arch x86_64 -arch x86_64 build/temp.macosx-10.7-x86_64-3.7/circbuf.o -L../build -lcpysim -o /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so -stdlib=libc++ -g

В обеих командах присутствует флаг -g.

Шаг 3: запустить отладчик

Наконец, я запускаю свою программу с помощью gdb

(base) cmac-2:sim colinww$ gdb python3
(gdb) run system_sim.py

Он выводит кучу вещей, связанных с системными файлами (кажется, не связанными), и, наконец, запускает мою программу, и когда она вызывает ошибку:

Thread 2 received signal SIGSEGV, Segmentation fault.
0x0000000a4585469e in cpysim::DataBuffer<double>::Write(long, long, double) () from /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so
(gdb) info local
No symbol table info available.
(gdb) where
#0  0x0000000a4585469e in cpysim::DataBuffer<double>::Write(long, long, double) () from /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so
#1  0x0000000a458d6276 in cpysim::ChannelFilter::Filter(long, long, long) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#2  0x0000000a458b0d29 in __pyx_pf_6chfilt_6ChFilt_4filter(__pyx_obj_6chfilt_ChFilt*, long, long, long) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#3  0x0000000a458b0144 in __pyx_pw_6chfilt_6ChFilt_5filter(_object*, _object*, _object*) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#4  0x000000010002f1b8 in _PyMethodDef_RawFastCallKeywords ()
#5  0x000000010003be64 in _PyMethodDescr_FastCallKeywords ()

Как я упоминал выше, я думаю, что проблема начинается на начальном этапе компиляции. Это не имеет ничего общего с Cython, я просто вызываю gcc из командной строки, передавая флаг -g.

(base) cmac-2:system-model colinww$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Любая помощь приветствуется, спасибо!

UPDATE

Я удалил тег gcc и изменил его на clang. Поэтому я думаю, что теперь я в замешательстве, если Apple будет использовать псевдоним gcc для clang, не означает ли это, что в «этом режиме» он должен вести себя как gcc (и, подразумевается, кто-то убедился, что это так).

ОБНОВЛЕНИЕ 2

Итак, я никогда не мог заставить символы отладки появляться в отладчике, и мне пришлось прибегнуть к множеству интересных операторов if-printf, но проблема была в том, что индексная переменная стала неопределенной. Так что спасибо за все предложения, но проблема более или менее решена (до следующего раза). Спасибо!

1 Ответ

3 голосов
/ 28 июня 2019

компоновщик macOS не связывает отладочную информацию в окончательный двоичный файл, как это обычно делают компоновщики в других Unixen. Вместо этого он оставляет отладочную информацию в файлах .o и записывает «карту отладки» в двоичный файл, который сообщает отладчику, как найти и связать отладочную информацию, считанную из файлов .o. Карта отладки удаляется при удалении двоичного файла.

Таким образом, вы должны убедиться, что вы не перемещаете и не удаляете свои файлы .o после последней ссылки, и что вы не удаляете двоичный файл, который отлаживаете, перед его отладкой.

Вы можете проверить наличие карты отладки, выполнив:

$ nm -ap <PATH_TO_BINARY> | grep OSO

Вы должны увидеть вывод как:

000000005d152f51 - 03 0001 OSO /Path/To/Build/Folder/SomeFile.o

Если вы не видите, что исполняемый файл, вероятно, удален. Если файла .o нет, то кто-то очистил вашу папку сборки раньше, чем должен был.

Я также не знаю, знает ли gdb, как читать карту отладки в macOS. Если присутствуют записи карты отладки и файлы .o, вы можете попробовать lldb и посмотреть, сможет ли это найти информацию отладки. Если это возможно, то, скорее всего, это проблема gdb-on-macOS. Если все файлы OSO и .o присутствуют, то что-то, о чем я не могу догадаться, пошло не так, и, возможно, стоит указать ошибку с http://bugreporter.apple.com.

...