Введение
Внезапное аварийное завершение процесса (падение с ошибкой Segmentation Fault) или появление сигнатур core dump оставляет разработчика наедине с шестнадцатеричными указателями памяти, по которым трудно понять истинную причину сбоя. В данном руководстве подробно разбирается утилита addr2line, способная в считанные мгновения преобразовать виртуальный адрес инструкции в конкретный файл исходного кода и точный номер проблемной строки. Ниже разобран полный практический цикл: от сборки с отладочной информацией (-g) до деманглинга идентификаторов C++ (-C) и разворачивания цепочек вызовов инлайновых функций (-i).
1. Подготовка окружения: инсталляция инструментария binutils и компилятора gcc
Для работы с утилитой addr2line и трансляции демонстрационных программ необходимо убедиться в наличии пакетов binutils и gcc. Установка выполняется стандартной системной командой: sudo apt-get update -qq && sudo apt-get install -y binutils gcc.

Проверить корректность размещения исполняемого файла в системе и узнать текущую ревизию пакета можно вызовом addr2line -v.
Ключевая задача addr2line — сопоставление шестнадцатеричных адресов из стектрейса аварии с соответствующими строками исходного текста программы.
⚙️ [Ключевые флаги командной строки]
-e : указывает путь к исследуемому двоичному файлу ELF.-f : запрашивает вывод наименования функции параллельно с позицией строки.-C : восстанавливает исходные человекочитаемые сигнатуры функций (деманглинг C++).-p : форматирует сведения об ошибке в единую удобную для чтения строку.-a : дублирует исходный шестнадцатеричный адрес перед результатом преобразования.-i : выполняет обратную трассировку для кода, развернутого компилятором как inline.

2. Создание тестового стенда и сборка программы с символами отладки (-g)
Создадим изолированное рабочее пространство для практических экспериментов и перейдем в него с помощью связки mkdir -p ~/addr2line_lab && cd ~/addr2line_lab.

Сформируем файл test_crash.c, содержащий функцию faulty_function, на примере которой будет производиться разбор адресов.

Чтобы бинарник содержал разметку DWARF, необходимую для работы addr2line, и не подвергался агрессивным оптимизациям, скомпилируем его вызовом gcc -g -O0 test_crash.c -o test_crash.

Для извлечения начального адреса процедуры faulty_function обратимся к таблице символов посредством nm test_crash | grep faulty_function.
Как видно из полученных данных, точка входа процедуры расположена по смещению 0000000000001149.

3. Определение исходного файла и строки по смещению в памяти (ключи -e и -f)
Для автоматизации подстановки зафиксируем полученный адрес в переменной окружения shell: FUNC_ADDR=$(nm test_crash | grep faulty_function | awk '{print $1}').

Передадим исследуемый ELF-файл через флаг -e вместе с сохраненным адресом, чтобы извлечь исходное расположение в коде (test_crash.c:3).

Добавив параметр -f, мы дополним отчет прямым именем сбойной функции (faulty_function), расположенной по указанному адресу.

4. Расширенный анализ: деманглинг C++ (-C) и раскрутка встроенного кода (-i, -p)
Для перехода к исследованию бинарников C++ доустановим компилятор g++ командой sudo apt-get install -y g++.

Создадим исходный модуль test_cpp.cpp, реализующий цепочку вызовов с использованием оптимизируемой подстановки inline.

Скомпилируем программу с оптимизацией -O2, вынуждающей компилятор встраивать тело функции, сохранив отладочные символы: g++ -g -O2 test_cpp.cpp -o test_cpp.

Считаем виртуальное смещение точки входа main из таблицы символов и экспортируем его в переменную shell: MAIN_ADDR=$(nm test_cpp | grep 'main' | head -n 1 | awk '{print $1}').

Воспользуемся ключом -C для раскодирования манглированных имен, а параметры -i и -p применены для компактного вывода иерархии инлайновых вызовов.
Появление в выводе маркера ??:0 сигнализирует о том, что механизм оптимизации кода либо формирование Position Independent Executable (PIE) препятствуют прямой статической привязке адреса без учета базового адреса загрузки модуля.

Мы подробно рассмотрели методику выявления мест критических сбоев в Linux с применением утилиты addr2line.
Включение этого инструмента в повседневный арсенал системного инженера позволяет быстро переводить абстрактные дампы памяти в конкретные строки кода и существенно экономить время при расследовании инцидентов.