【问题标题】:porting linux 32 bit app to 64 bit?将 linux 32 位应用程序移植到 64 位?
【发布时间】:2011-04-03 05:46:21
【问题描述】:

我即将将非常大规模的应用程序移植到 64 位, 我注意到在网上有一些文章显示 这种移植的许多陷阱, 我想知道是否有任何工具可以帮助移植到 64 位,这意味着 在代码中找到需要更改的地方....也许启用警告的 g​​cc... 是否足够好?有什么更好的吗?

编辑:伙计们,我正在寻找一个可能对编译器来说是完整的工具, 我知道 GCC 可以提供帮助,但我怀疑它会发现所有不可移植的问题
将在运行时发现....可能是强调的静态代码分析工具 移植到 64 位?

谢谢

【问题讨论】:

    标签: c++ c linux 64-bit


    【解决方案1】:

    首先,为什么会有“移植”?

    考虑到大多数发行版都为十多年来愉快地提供了 32 位和 64 位变体。因此,除非您以真正不可移植的方式进行编程(并且您几乎必须尝试),否则您应该没问题。

    【讨论】:

    • 运行时错误怎么办?你绝对相信这个问题的编译器警告吗?我对此表示怀疑。
    • 太容易掉入不可移植的陷阱,即使是像 sprintf("%u",sizeof something); 这样简单的东西。会咬你,根据我的经验,大型应用程序通常已经开发了十多年,有太多人在乱搞,你永远不知道当你在其他东西上编译/运行它时会爆炸什么,而不是它曾经运行过
    • 啊,以一种真正不可移植的方式编程,这很容易...将指针转换为int,在使用va_arg 函数时具有隐式整数传播,看似常量会改变它们的符号...不要不用担心。
    • 你们所说的实际上是在强调重新编译 64 位是不够的......
    • 我当然会,我也会考虑编译器的警告,如果有任何工具可以帮助找到未修复的问题,我正在搜索什么。
    【解决方案2】:

    在 64 位操作系统中编译项目怎么样? gcc 编译器看起来像这样的工具:)

    【讨论】:

    • 你知道不是每个应用程序都可以通过重新编译来移植到 64 位吗?你知道有很多问题会导致运行时出现问题而不是编译时出现问题吗??
    • 同意,但第一步仍然是编译...大多数不正确的东西都没有被编译,比如分配一个指向 32 位整数值的指针,或者不同的 int 和 size_t 大小。
    • 并提高警告级别:-pedantic -Wall -Wextra 是一个好的开始。它会帮助你发现一些问题。当然,据我所知,没有任何工具可以纠正您对某些数据类型、对齐、汇编等的假设。这太复杂了。
    【解决方案3】:

    Here 是一个向导。 Another one

    某些数据类型的大小在 32 位和 64 位操作系统中是不同的,因此请检查代码假设数据类型大小的位置。例如,如果您将一个指向 int 的指针转换为 int,则在 64 位中将无法工作。这应该可以解决大部分问题。

    如果您的应用使用第三方库,请确保这些库也可以在 64 位中运行。

    【讨论】:

    • 我对这些指南很熟悉,但问题是,是否有任何工具可以节省人工时间,是否足够?而不是在代码中搜索数千个可疑位置 ....
    • 嗨,我有类似的将 32 代码移植到 64 位架构的问题。如果我使用“gcc -m32”进行编译,移植到 64 位是否应该是透明的?
    【解决方案4】:

    一个好的工具叫做grep ;-) 做

    grep -nH -e '\<int\>\|\<short\>\|\<long\>' *
    

    并用适当的替换这些基本整数类型的所有裸露用法:

    • 数组索引应该是size_t
    • 指针转换应该是uintptr_t
    • 指针差异应该是 prtdiff_t
    • 假设宽度为 N 的类型 应该是uintN_t

    等等,我可能忘记了一些。 然后 gcc 会告诉你所有警告。您还可以使用clang 作为编译器,它可以提供更多诊断信息。

    【讨论】:

    • 这也许不错,但我不确定它是否涵盖所有陷阱...我正在寻找一个涵盖所有陷阱的工具以减少运行时错误 ....
    • @_Avishay_:当然还有其他的,但我真的认为这些是主要的,通常隐式整数促销是其余的。还可以肯定的是,如果代码写得不好,这会给你很多结果,但每个结果都指向一个潜在的问题点。如果您在任何情况下都不解决所有问题,您将不安全。并且还可以肯定,有时这很难猜到,因为仅使用 int 例如根本缺少任何自动工具所需的语义标签……我个人不相信存在将坏代码转换为好代码的工具一。
    • 我不是在寻找将其从不可移植代码转移到可移植代码的工具,这对于自动工具来说相当困难,但对于在代码中搜索不可移植位置的工具来说似乎更容易也许编译器wanning不会找到....
    • @_Avishay_:我不同意。要求从 32 位移植到 64 位,在很大程度上与要求将不可移植的代码转移到可移植的代码相同。我给的grep 给你带来了很多麻烦。对于其余部分,例如显式强制转换或整数提升,它们是语言的一部分,没有工具能够判断它们是否是故意的。
    • 嗨,我有类似的将 32 代码移植到 64 位架构的问题。如果我使用“gcc -m32”进行编译,移植到 64 位是否应该是透明的?
    【解决方案5】:

    这里是一个 Oracle 网页的链接,该网页讨论了将 32 位应用程序移植到 64 位时经常遇到的问题:

    http://www.oracle.com/technetwork/server-storage/solaris/ilp32tolp64issues-137107.html

    其中一节讨论了如何使用 lint 来检测一些常见错误。这是该部分的副本:

    使用 lint 实用程序检测 64 位长和指针类型的问题 使用 lint 检查为 32 位和 64 位编译环境编写的代码。指定 -errchk=longptr64 选项以生成 LP64 警告。还可以使用-errchk=longptr64 标志检查对长整数和指针大小为 64 位且普通整数大小为 32 位的环境的可移植性。 -errchk=longptr64 标志检查指针表达式和长整数表达式到纯整数的分配,即使使用显式转换也是如此。

    使用-errchk=longptr64,signext 选项查找代码,其中正常的 ISO C 值保留规则允许在无符号整数类型的表达式中扩展有符号整数值的符号。如果要检查打算在 Solaris 64 位 SPARC 或 x86 64 位环境中运行的代码,请使用 lint 的 -m64 选项。

    当 lint 生成警告时,它会打印出问题代码的行号、描述问题的消息以及是否涉及指针。警告消息还指示所涉及数据类型的大小。当您知道涉及到一个指针并且您知道数据类型的大小时,您可以找到特定的 64 位问题并避免 32 位和更小类型之间的预先存在的问题。

    您可以通过在前一行放置“NOTE(LINTED())”形式的注释来抑制给定代码行的警告。当您希望 lint 忽略某些代码行(例如强制转换和赋值)时,这很有用。使用“NOTE(LINTED())”注释时要格外小心,因为它可以掩盖实际问题。当您使用 NOTE 时,还包括#include。有关详细信息,请参阅 lint 手册页。

    【讨论】:

      猜你喜欢
      • 2020-10-28
      • 2011-03-11
      • 1970-01-01
      • 2017-12-11
      • 2010-12-18
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      • 2014-12-05
      相关资源
      最近更新 更多