如何难以捉摸可以检测64位可移植性问题? [英] How can elusive 64-bit portability issues be detected?

查看:387
本文介绍了如何难以捉摸可以检测64位可移植性问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现了一个类似的片段在某些(C ++)code我preparing为64位端口。

I found a snippet similar to this in some (C++) code I'm preparing for a 64-bit port.

int n;
size_t pos, npos;

/* ... initialization ... */

while((pos = find(ch, start)) != npos)
{
    /* ... advance start position ... */

    n++; // this will overflow if the loop iterates too many times
}

虽然我严重怀疑这实际上会产生一个问题,即使内存密集型应用程序,这是值得期待的,从理论的角度来看,因为类似的错误可以表面上的将会的原因的问题。 (修改 N 在上面的例子中,甚至小文件可能溢出柜台上。)

While I seriously doubt this would actually cause a problem in even memory-intensive applications, it's worth looking at from a theoretical standpoint because similar errors could surface that will cause problems. (Change n to a short in the above example and even small files could overflow the counter.)

静态分析工具是有用的,但他们不能直接检测到这种类型的错误。 (还没有,反正。)反 N 不参加,而 EX pression所有,所以这不是那么简单,其他循环(其中,铸字错误给出错误的距离)。任何工具将需要确定该循环将执行超过2 31 倍,但是这意味着它需要能够估计多少次前pression ( POS =发现(CH,开始))!=非营利组织将评估为真不小的壮举!即使一个工具,可确定循环的可以的执行超过2 31 倍(比如,因为它承认了查找功能正在开发一个字符串),它如何能知道循环的不会的执行超过2 64 次,溢满一个为size_t 价值呢?

Static analysis tools are useful, but they can't detect this kind of error directly. (Not yet, anyway.) The counter n doesn't participate in the while expression at all, so this isn't as simple as other loops (where typecasting errors give the error away). Any tool would need to determine that the loop would execute more than 231 times, but that means it needs to be able to estimate how many times the expression (pos = find(ch, start)) != npos will evaluate as true—no small feat! Even if a tool could determine that the loop could execute more than 231 times (say, because it recognizes the find function is working on a string), how could it know that the loop won't execute more than 264 times, overflowing a size_t value, too?

这似乎很清楚,到最后确定并修正这种错误,需要一个人的眼睛,但是否有模式,放弃这种错误,因此可以手动检查?存在哪些类似的错误,我应该警惕的?

It seems clear that to conclusively identify and fix this kind of error requires a human eye, but are there patterns that give away this kind of error so it can be manually inspected? What similar errors exist that I should be watchful for?

修改1:由于 INT 类型本身是有问题的,这种错误可以通过检查这些类型的每个实例都可以找到。然而,鉴于其在传统C ++ code无处不在,我不知道这是实用的一个大的软件。还有什么赠送这个错误?在每个,而循环可能表现出某种类似这样的错误呢? (循环当然也不能幸免于它!)如何不好是这种类型的错误,如果我们不处理如 16位类型总之

EDIT 1: Since short, int and long types are inherently problematic, this kind of error could be found by examining every instance of those types. However, given their ubiquity in legacy C++ code, I'm not sure this is practical for a large piece of software. What else gives away this error? Is each while loop likely to exhibit some kind of error like this? (for loops certainly aren't immune to it!) How bad is this kind of error if we're not dealing with 16-bit types like short?

编辑2:下面是另外一个例子,说明如何这个错误出现在循环

EDIT 2: Here's another example, showing how this error appears in a for loop.

int i = 0;
for (iter = c.begin(); iter != c.end(); iter++, i++)
{
    /* ... */
}

这是从根本上相同的问题:循环指望一些变量,从不直接与更多类型的交互。变量仍然可以溢出,但没有编译器或工具检测铸件错误。 (严格地说,是没有的。)

It's fundamentally the same problem: loops are counting on some variable that never directly interacts with a wider type. The variable can still overflow, but no compiler or tool detects a casting error. (Strictly speaking, there is none.)

修改3:的code我正在使用是的非常的大。 (10-15万行code C ++的一个人。)这是不可能检查所有的,所以我的方式,以确定这样的,即使它会导致较高的假阳性率的问题(特别感兴趣)自动运行。

EDIT 3: The code I'm working with is very large. (10-15 million lines of code for C++ alone.) It's infeasible to inspect all of it, so I'm specifically interested in ways to identify this sort of problem (even if it results in a high false-positive rate) automatically.

推荐答案

code的评论。找一帮聪明的人在看code的。

Code reviews. Get a bunch of smart people looking at the code.

使用的 INT 是一个警告信号,因为这些类型的范围不是在标准中定义。大多数使用应更改为新 int_fastN_t 类型< stdint.h> ,使用与序列化处理,以 intN_t 。嗯,其实这些< stdint.h> 类型应该用的typedef 新的应用程序特定类型

Use of short, int, or long is a warning sign, because the range of these types isn't defined in the standard. Most usage should be changed to the new int_fastN_t types in <stdint.h>, usage dealing with serialization to intN_t. Well, actually these <stdint.h> types should be used to typedef new application-specific types.

这个例子实际上应该是:

This example really ought to be:

typedef int_fast32_t linecount_appt;
linecount_appt n;

这EX presses一个设计假设linecount适合在32位,也可以很容易地修复code。如果设计要求的变化。

This expresses a design assumption that linecount fits in 32 bits, and also makes it easy to fix the code if the design requirements change.

这篇关于如何难以捉摸可以检测64位可移植性问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆