【问题标题】:How to get gdb on Linux to find source file for binary cross compiled on windows如何在 Linux 上获取 gdb 以查找在 Windows 上交叉编译的二进制源文件
【发布时间】:2015-01-22 10:54:38
【问题描述】:

我正在尝试为 Linux 目标调试在 Windows 主机上交叉编译的应用程序。

问题: 因为初始编译是在 Windows 中进行的,所以二进制文件中存储的源文件路径的格式为 C:\Users\foo\project\...。在 Linux 目标上,我将源文件放在 \home\foo\project\.... 下,默认情况下 gdb 找不到源文件,因为路径不同。

到目前为止我所尝试的:

  1. 在 gdb 中使用“目录”命令为正在调试应用程序的目标 Linux 系统中的 .c 源文件提供准确路径。这可行,但不幸的是实际上有数百个文件,因此这种解决方案是不切实际的。

  2. 使用 set substitute-path C:\\Users\\foo\\project /home/foo/project 命令让 gdb 替换所有前缀。请注意,\\ 似乎是必要的,以便show substitute-path 注册正确的字符串。不幸的是,这不起作用。我的猜测是,substitute-path 命令不处理 ms-dos 样式的路径。

  3. 尝试将调试信息分离到单独的 .debug 文件中(请参阅 How to generate gcc debug symbol outside the build target?),然后使用 debugedit 通过命令 debugedit --base-dir=C:\Users\foo --dest-dir=/home/foo project.debug 更改路径。不幸的是,这也不起作用。 debugedit 似乎可以正常工作,如果现有路径都是 UNIX/Linux 之类的,但似乎不适用于 ms-dos 样式的路径。

我查看了 stackoverflow,虽然有类似的主题,但我找不到任何对我有帮助的东西。非常感谢任何建议/帮助。我意识到从 Windows 进行交叉编译是一种非常迂回的方式,但目前无法避免。

谢谢

【问题讨论】:

    标签: linux windows gdb cross-compiling


    【解决方案1】:

    虽然这是一个相当老的问题,但我确实遇到了同样的问题。我设法解决了它,但在二进制可执行文件上使用了sed...(是的,有点“hack-ish”,但没有找到其他方法)。使用sed,我已经成功地替换了可执行文件中的符号路径,诀窍是新路径的长度应该与旧路径的长度相同。

    sed -i "s#C:/srcpath#/srcpath/.#g" ./executable
    

    确保新路径的长度相同,否则可执行文件会卡住。

    【讨论】:

    • 太棒了。一个小时以来我一直在反对这个。
    【解决方案2】:

    我也有同样的问题。您的选项 1 并没有您想象的那么糟糕,因为您可以使用类似以下 python 代码的脚本创建所有“目录”命令:

    def get_directory_paths():
        return_array = list()
        unix_path = os.path.join('my','unix','path')
        for root, dirs, files in os.walk(unix_path):
            for dir in dirs:
                full_unix_path = os.path.join(root,dir)
                escaped_unix_path = re.sub("\s", "\\\\ ", full_unix_path)
                return_array.insert(0, "directory " + escaped_unix_path)
        return '\n'.join(return_array)
    

    缺点是如果你在不同的目录中有两个同名的源文件,我不认为 gcc 可以选择正确的一个。这让我很担心,但在我的特殊情况下,我认为我是安全的。

    对于选项 2(我怀疑它会修复 #1 中的别名条件),我认为问题在于根据 linux,替换不是以“文件分隔符”结尾的,因此它们没有被应用:

    为避免意外的替换结果,仅当目录名称的 from 部分以目录分隔符结尾时才应用规则。例如,将 /usr/source 替换为 /mnt/cross 的规则将应用于 /usr/source/foo-1.0,但不会应用于 /usr/sourceware/foo-2.0。并且因为替换只应用于目录名的开头,所以这条规则也不会应用于 /root/usr/source/baz.c。”(来自https://sourceware.org/gdb/current/onlinedocs/gdb/Source-Path.html#index-set-substitute_002dpath

    我没有尝试过像你的 #3 这样的东西,我也考虑过类似@dragn 的建议,但在我的情况下,路径甚至不接近相同的长度,所以这将是一个问题。

    我认为我坚持使用 #1 和脚本,但如果有人有其他建议,我很感兴趣 :-)

    【讨论】:

      猜你喜欢
      • 2010-10-09
      • 1970-01-01
      • 2011-05-18
      • 2012-03-03
      • 1970-01-01
      • 2022-01-03
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多