📄

Отладка Core-дампов С++ проектов при помощи VSCode

01.10.2025 VSCode

Отладка core dump файлов — это критически важный навык для любого C++ разработчика. Когда ваше приложение неожиданно падает с сегфолтом или другими критическими ошибками, core dump файл становится вашим главным инструментом для расследования причин катастрофы. В этой статье мы подробно разберем, как настроить VSCode для комфортной и эффективной отладки core файлов, превратив этот сложный процесс в рутинную операцию.

Что такое Core Dump?

Core Dump (дамп памяти) — это снимок состояния памяти процесса в момент его аварийного завершения. Представьте себе, что это как «черный ящик» в авиации — он сохраняет всю информацию о том, что происходило с программой в последние моменты ее жизни. Core файл содержит:

  • Состояние всех переменных и объектов
  • Содержимое стека вызовов
  • Информацию о потоках выполнения
  • Состояние регистров процессора
  • И многое другое…

Предварительные требования

Прежде чем мы начнем, убедитесь, что у вас установлены следующие компоненты:

  • Visual Studio Code — наша основная среда разработки
  • Расширение C/C++ от Microsoft — обеспечивает поддержку отладки
  • GDB (GNU Debugger) — собственно, сам отладчик
  • Core файл — который мы собираемся анализировать
  • Исходный код — точно соответствующий тому, который использовался при сборке упавшего бинарника
  • Отладочные символы — либо в самом бинарнике, либо в отдельном файле

О том, откуда взять отладочные символы мы напишем в следующей статье.

Детальная настройка launch.json

Давайте разберем каждую важную часть конфигурации, которую я предоставил выше.

Базовые параметры

{
    "name": "Debug Core File",
    "type": "cppdbg",
    "request": "launch",
    "program": "/usr/sbin/my-cpp-project",
    "coreDumpPath": "/root/core/core",
    "cwd": "/root/my-cpp-project"
}
  • name — понятное название конфигурации, которое вы увидите в выпадающем списке отладки
  • type — всегда cppdbg для C++ отладки
  • request — launch означает, что мы запускаем отладку (хотя используем core файл)
  • program — абсолютный путь к исполняемому файлу, который упал
  • coreDumpPath — абсолютный путь к core dump файлу
  • cwd — рабочая директория, должна указывать на корень вашего проекта

Настройки отладчика

{
    "MIMode": "gdb",
    "miDebuggerPath": "/usr/bin/gdb",
    "stopAtConnect": true,
    "externalConsole": false
}
  • MIMode — указывает, что мы используем GDB через Machine Interface
  • miDebuggerPath — путь к GDB (проверьте через which gdb)
  • stopAtConnect — останавливаться сразу при подключении, дает контроль до выполнения команд
  • externalConsole — false использует встроенную консоль VSCode

Маппинг путей исходного кода

{
    "sourceFileMap": {
        "/builds/company/my-cpp-project": "/root/my-cpp-project"
    }
}

Это чрезвычайно важный параметр! Он решает одну из самых частых проблем — когда core файл был сгенерирован на сервере или в CI/CD системе, а вы отлаживаете на локальной машине. GDB ищет исходные файлы по путям, которые были захардкожены при компиляции. Этот параметр говорит: «Когда GDB ищет файлы в /builds/company/my-cpp-project, покажи ему файлы из /root/my-cpp-project на моей локальной машине».

Логирование и трассировка

{
    "logging": {
        "engineLogging": true,
        "trace": true,
        "traceResponse": true
    }
}

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

 Команды настройки GDB

Самая мощная часть конфигурации — секция setupCommands. Давайте разберем каждую команду:

Блокировка автоматической загрузки библиотек

{
    "description": "Prevent host solib loading (search path)",
    "text": "-gdb-set solib-search-path /nonexistent",
    "ignoreFailures": true
}

Эта команда предотвращает автоматическую загрузку shared libraries с вашей локальной системы. Это критически важно, потому что версии библиотек на вашей машине могут не совпадать с теми, что были у упавшего процесса.

Подмена путей к исходному коду

{
    "description": "Substitute remote build paths with local source root", 
    "text": "-interpreter-exec console \"set substitute-path /builds/company/my-cpp-project /root/my-cpp-project\"",
    "ignoreFailures": true
}

Альтернативный способ маппинга путей. Иногда дублирование с sourceFileMap необходимо для полного покрытия всех случаев.

Добавление путей к исходному коду

{
    "description": "Add local source directory to GDB search path",
    "text": "-interpreter-exec console \"directory /root/my-cpp-project\"",
    "ignoreFailures": true
}

Прямо говорит GDB: «Ищи исходные файлы в этой директории».

Настройка отладочной информации о потоках

{
    "description": "Enable libthread_db auto-load", 
    "text": "-gdb-set auto-load libthread-db on",
    "ignoreFailures": true
}

Включает автоматическую загрузку информации о потоках, что необходимо для корректной отладки многопоточных приложений.

Улучшение читаемости вывода

{
    "description": "Enable pretty-printing",
    "text": "-enable-pretty-printing", 
    "ignoreFailures": true
}

Включает «красивый вывод» для STL контейнеров и сложных структур данных. Вместо нечитаемого набора байтов вы увидите понятное представление std::vectorstd::map и других контейнеров.

Итоговый launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug Core File",
            "type": "cppdbg",
            "request": "launch",
            "program": "/usr/sbin/my-cpp-project",
            "coreDumpPath": "/root/core/core",
            "cwd": "/root/my-cpp-project",
            "MIMode": "gdb",
            "miDebuggerPath": "/usr/bin/gdb",
            "launchCompleteCommand": "None",
            "stopAtConnect": true,
            "externalConsole": false,
            "console": "internalConsole",
            "sourceFileMap": {
                "/builds/company/my-cpp-project": "/root/my-cpp-project"
            },
            "logging": {
                "engineLogging": true,
                "trace": true,
                "traceResponse": true
            },
            "miDebuggerArgs": "-iex \"set solib-search-path /nonexistent\" -iex \"set auto-solib-add off\"",
            "setupCommands": [
                {
                    "description": "Prevent host solib loading (search path)",
                    "text": "-gdb-set solib-search-path /nonexistent",
                    "ignoreFailures": true
                },
                {
                    "description": "Substitute remote build paths with local source root",
                    "text": "-interpreter-exec console \"set substitute-path /builds/company/my-cpp-project /root/my-cpp-project\"",
                    "ignoreFailures": true
                },
                {
                    "description": "Add local source directory to GDB search path",
                    "text": "-interpreter-exec console \"directory /root/my-cpp-project\"",
                    "ignoreFailures": true
                },
                {
                    "description": "Enable libthread_db auto-load",
                    "text": "-gdb-set auto-load libthread-db on",
                    "ignoreFailures": true
                },
                {
                    "description": "Keep shared library auto load disabled",
                    "text": "-gdb-set auto-solib-add off",
                    "ignoreFailures": true
                },
                {
                    "description": "Set pagination off",
                    "text": "-gdb-set pagination off",
                    "ignoreFailures": true
                },
                {
                    "description": "Enable pretty-printing",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

Также, иногда могут понадобиться отдельные настройки GDB, их можно задать в файле .gdbinit, который необходимо поместить в директорию проекта. Ниже представлен пример содержимого:

# Конфигурация GDB для отладки core файлов с debug символами
# Этот файл автоматически загружается GDB

# КРИТИЧЕСКИ ВАЖНЫЕ настройки для быстрой загрузки core файлов
set auto-solib-add off
set print symbol-filename off
set pagination off
set confirm off

# Ограничения на объём выводимых значений
set max-value-size 1024

# Отключаем все предупреждения
set complaints 0

# Минимальные настройки отображения
set print pretty on
set print array on
set print elements 200

# Ускоряем работу с потоками (после загрузки core это безопасно)
set non-stop off

# Отключаем ненужные отладочные логи
set debug infrun 0

# Пути и загрузка символов выполняются через setupCommands в launch.json в правильном порядке

Последние статьи

📄

Профилирование памяти в С++

Проблема стабильности программного обеспечения В процессе разработки и эксплуатации программного обеспечения на языке C++ нередко возникают ситуации, требующие детального анализа…

04.10.2025 CXX