debugging 如何使用vscode调试libtool项目?

cl25kdpy  于 2023-10-24  发布在  Vscode
关注(0)|答案(1)|浏览(161)

我有一个使用libtools的C++项目。当libtool构建一个程序时,它将二进制文件放在一个目录中(.libs),并将一个同名的 Package 脚本放在build目录中,如下所示:

project/
+- libtool
+- build/
   +- a.out           <<< this is a script, not a binary
   +- .libs/
      +- a.out
      +- lt-a.out

为了从命令行调试libtool程序,您需要调用:
../libtool --mode=execute gdb a.out
然而,直接调试build/a.out是不可能的,因为它不是二进制文件。我发现我可以在vscode内部调试程序,如果我将启动配置指向.libs/a.out文件,如下所示:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/.libs/a.out",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}/build",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

有没有办法通过libtool Package 器调用二进制文件?
这样做有什么好处吗?

db2dz4w8

db2dz4w81#

要使用vscode调试libtool程序,您需要一个 Package 器脚本来打乱用于启动调试器的命令行,并对launch.json配置进行一些更改。
下面是我使用的一个 Package 器脚本(vscode-lt-launch.sh):

#!/bin/bash
# vscode-lt-launch.sh
# libtool wrapper for vscode debugging

# Copyright (c) 2023, Radu Hociung
# This file is in the public domain, free to use for any purpose.
#
# Will be called with the following args, which are re-ordered to create the
#  correct libtool execution command line:
# --interpreter=mi {miDebuggerArgs} --tty=/dev/pts/17
# 
# The VScode launch.json configuration should contain the following fields:
#
# "miDebuggerPath" should be set as "./vscode-lt-launch.sh" (this file)
#
# "miDebuggerArgs" should be set as 
#             "gdb ${workspaceFolder}/libtool {program-name-libtool-wrapper}"
#             in launch.json
#
# "program" shoud be set to "src/.libs/{libtool-built-program-name}"
#
# "additionalSOLibSearchPath" shoud be set to "lib/.libs/" or wherever your
#             program's own shared libs are, if your software also
#             builds shared libs

# Example VScode launch.json configuration (the program name is "myprogram"):
#        {
#            "name": "(gdb) Launch",
#            "type": "cppdbg",
#            "request": "launch",
#            "program": "src/.libs/myprogram",
#                       ^^^^^^^^^^^^^^^^^^^^^
#            "additionalSOLibSearchPath": "lib/.libs/",
#                                         ^^^^^^^^^^^^
#            "args": ["-4", "-myprogram-args"],
#            "stopAtEntry": true,
#            "cwd": "${workspaceFolder}",
#            "externalConsole": false,
#            "miDebuggerPath": "./vscode-lt-launch.sh",
#                              ^^^^^^^^^^^^^^^^^^^^^^^
#            "miDebuggerArgs": "gdb ${workspaceFolder}/libtool src/myprogram",
#                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#            "MIMode": "gdb",
#            "setupCommands": [
#                {
#                    "description": "Enable pretty-printing for gdb",
#                    "text": "-enable-pretty-printing",
#                    "ignoreFailures": true
#                },
#                {
#                    "description": "Set Disassembly Flavor to Intel",
#                    "text": "-gdb-set disassembly-flavor intel",
#                    "ignoreFailures": true
#                }
#            ]
#        },

# $1 is "--interpreter=mi", inserted by vscode
# $2 is "gdb" set with miDebuggerArgs
# $3 is "${workspaceFolder}/libtool" set with miDebuggerArgs
# $4 is "src/myprogram" set with miDebuggerArgs
# $5 is "--tty=/dev/pts/19", inserted by vscode

# LD_LIBRARY_PATH is set here but shouldn't be. Instead, libtool should
# add -rpath to the link command, so that --mode=execute runs the program
# with the correct LD_LIBRARY_PATH.
# I'm no libtool expert.
# If you know how to get libtool to add -rpath at link time, please let me know.
build_dir=$(dirname "$3")
export LD_LIBRARY_PATH=${build_dir}/lib/.libs/:$LD_LIBRARY_PATH

# Reorder the args and use solib-absolute-prefix to prevent GDB from seaching
# the / prefix first for shared libs.
# gdb will search the shared libs in the following locations, in this order:
#   1. additionalSOLibSearchPath,
#   2. $LD_LIBRARY_PATH
#   3. system linker's default search path (/lib:/usr/lib:...)
# This ensures the program runs with its own shared libs even if a copy could
# be found installed in /usr/lib/ or other system location.

[ -x "$3" ] && "$3" --mode=execute "$2" \
     -ex "set solib-absolute-prefix /dev/null" "$1" "$5" "$4"

脚本应该被复制到项目的根目录。LD_LIBRARY_PATH设置应该不是必需的,这是一个我不知道如何消除的黑客。没有它,gdb运行的可执行文件将链接到系统库,而不是暂存库。如果你知道如何删除它,我希望在下面发表评论。
vscode launch.json将需要类似于以下的配置,如 Package 器脚本中所述:

{
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "src/.libs/myprogram",
//                     ^^^^^^^^^^^^^^^^^^^^^
            "additionalSOLibSearchPath": "lib/.libs/",
//                                       ^^^^^^^^^^^^
            "args": ["-4", "-myprogram-args"],
            "stopAtEntry": true,
            "cwd": "${workspaceFolder}",
            "externalConsole": false,
            "miDebuggerPath": "./vscode-lt-launch.sh",
//                            ^^^^^^^^^^^^^^^^^^^^^^^
            "miDebuggerArgs": "gdb ${workspaceFolder}/libtool src/myprogram",
//                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        },

如果在安装之前需要libtool来构建和测试你的应用,那么它需要 * 在它的运行状态下运行应用 *。
使用libtool Package 器有什么好处吗?这个问题有点像问使用编译器构建应用程序或使用调试器调试应用程序是否有好处。
有时候人们不知道libtool有什么功能,只是“以防万一”地将其添加到项目中,但没有使用它的功能,因此使用libtool构建的项目通过直接调用二进制文件(src/.lib/myproprogram等)来链接和执行并不罕见,特别是对于没有依赖关系的小项目。
如果程序依赖于安装在staging area中的其他库,libtool将确保它在staging area libs上运行,即使系统上安装了同名的libs。例如,如果您正在测试对libc或libresolv等常见系统库的更改,您将暂存构建的libc/libresolv,然后针对暂存的lib构建/测试应用程序,而不是系统安装的lib。只有在隔离测试完成后,您才可以安装改进的libc。在此之前,libtool生成的 Package 器(例如“src/myprogram”)包含正确的链接信息,因此它可以针对暂存库执行。
libtool对于在调试环境中运行调试的应用程序是必不可少的,但是如果程序很简单,并且只依赖于系统上已经安装的库,那么在项目开始时可能不需要libtool。

相关问题