64 位移植 c++ - 跟踪基本类型、指针、算术的使用
64 Bit Porting c++ - track usage of fundamental types, Pointers, arithmetics
我们正在使用 gcc/linux 从 32 位移植到 LP64。我正在寻找一种方法来跟踪内存布局(long,Ptr)中发生变化的数据类型的使用情况。
我对这些类型的所有可能有问题 "interactions" 的位置很感兴趣。
Typedef 需要取消引用为内置类型,如 ULONG 和 DWORD -> unsigned long
可能的问题可能是:旧式强制转换、重新解释强制转换、算术、over/underflow、赋值、比较、常量、ptr 算术、sizeof、size_t 算术、隐式对话……随便你怎么说。
因为这不是用正则表达式做的一件小事,而且代码库很大,我需要以某种方式使其自动化。
我想我至少需要一个解析树/AST 以及一个符号 table。
我在不同阶段尝试了一些 GCC 的内部树转储,但仍然没有任何线索。
我还启用了编译器必须提供的所有警告;-)
也许任何人都可以给我提示在哪里寻找。 (我已经看到了这个看起来很有前途的语义设计工具包)
你是怎么做到的?尝试、测试、失败并处理错误?
我会试试 clang...
此致
如果可能的话,避免特意把它想成"LLP64",使用提供的数据类型(uintptr_t
、size_t
等),不妨有代码应该是别处更正。尤其不要假设 long
是 64 位。
I think i need at least a parse tree / AST along with a symbol table.
我认为不存在完美的解决方案,您可以搜索可用的静态分析工具来捕获许多可能的错误,但有些事情仍然会过去,并且检测其中一些错误所需的灵敏度级别可以给出很多误报。
编译器可以检测到您可以使用自己的解析器轻松找到的基本内容,例如:
auto x = (SomeTypeDefedThing)*some_pointer;
int y = some_long;
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
warning: conversion to ‘int’ from ‘long int’ may alter its value [-Wconversion]
显式整数转换是一个更大的问题,如果你有 x = (int)y
或 x = (long)y
等,编译器只是假设你的意思是转换,并确定 y
是否可以超出范围真的很棘手。
虽然您可能会在静态分析中找到它,但我预计这样的警告会非常嘈杂,因为这样的显式转换通常确实需要这样做。
如果您正在执行任何二进制文件或网络 IO,那可能是个问题。理想情况下,它将使用已经提供的类型编写,以便在不同的实现之间正常工作。此类代码可以采用多种形式并且难以简单地搜索,但如果您知道您的程序确实执行此类文件或网络操作,则应该很容易识别和手动检查。
如果您真的需要寻找一种在您的代码中非常常见但未被预先存在的编译器和静态分析工具检测到的特定模式,那么将您自己的模式放在一起可能会有所帮助。
Clang 提供了许多有用的库和工具供您查看。虽然 GCC(和其他工具链,如 MSVC)可能有你可以解析的中间文件格式,但我还没有看到它们被使用,而且关于这些的文档似乎少得多(如果完整的话)。
他们有一个介绍文档,你可以通过-ast-dump
编译得到ast。 https://clang.llvm.org/docs/IntroductionToTheClangAST.html
正确移植:
- 阅读Lessons on development of 64-bit C and C++ applications。
- 尝试 PVS-Studio 诊断(the 64-bit rule set) (free license)。
我们正在使用 gcc/linux 从 32 位移植到 LP64。我正在寻找一种方法来跟踪内存布局(long,Ptr)中发生变化的数据类型的使用情况。 我对这些类型的所有可能有问题 "interactions" 的位置很感兴趣。
Typedef 需要取消引用为内置类型,如 ULONG 和 DWORD -> unsigned long 可能的问题可能是:旧式强制转换、重新解释强制转换、算术、over/underflow、赋值、比较、常量、ptr 算术、sizeof、size_t 算术、隐式对话……随便你怎么说。
因为这不是用正则表达式做的一件小事,而且代码库很大,我需要以某种方式使其自动化。 我想我至少需要一个解析树/AST 以及一个符号 table。 我在不同阶段尝试了一些 GCC 的内部树转储,但仍然没有任何线索。 我还启用了编译器必须提供的所有警告;-) 也许任何人都可以给我提示在哪里寻找。 (我已经看到了这个看起来很有前途的语义设计工具包)
你是怎么做到的?尝试、测试、失败并处理错误? 我会试试 clang...
此致
如果可能的话,避免特意把它想成"LLP64",使用提供的数据类型(uintptr_t
、size_t
等),不妨有代码应该是别处更正。尤其不要假设 long
是 64 位。
I think i need at least a parse tree / AST along with a symbol table.
我认为不存在完美的解决方案,您可以搜索可用的静态分析工具来捕获许多可能的错误,但有些事情仍然会过去,并且检测其中一些错误所需的灵敏度级别可以给出很多误报。
编译器可以检测到您可以使用自己的解析器轻松找到的基本内容,例如:
auto x = (SomeTypeDefedThing)*some_pointer;
int y = some_long;
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] warning: conversion to ‘int’ from ‘long int’ may alter its value [-Wconversion]
显式整数转换是一个更大的问题,如果你有 x = (int)y
或 x = (long)y
等,编译器只是假设你的意思是转换,并确定 y
是否可以超出范围真的很棘手。
虽然您可能会在静态分析中找到它,但我预计这样的警告会非常嘈杂,因为这样的显式转换通常确实需要这样做。
如果您正在执行任何二进制文件或网络 IO,那可能是个问题。理想情况下,它将使用已经提供的类型编写,以便在不同的实现之间正常工作。此类代码可以采用多种形式并且难以简单地搜索,但如果您知道您的程序确实执行此类文件或网络操作,则应该很容易识别和手动检查。
如果您真的需要寻找一种在您的代码中非常常见但未被预先存在的编译器和静态分析工具检测到的特定模式,那么将您自己的模式放在一起可能会有所帮助。
Clang 提供了许多有用的库和工具供您查看。虽然 GCC(和其他工具链,如 MSVC)可能有你可以解析的中间文件格式,但我还没有看到它们被使用,而且关于这些的文档似乎少得多(如果完整的话)。
他们有一个介绍文档,你可以通过-ast-dump
编译得到ast。 https://clang.llvm.org/docs/IntroductionToTheClangAST.html
正确移植:
- 阅读Lessons on development of 64-bit C and C++ applications。
- 尝试 PVS-Studio 诊断(the 64-bit rule set) (free license)。