如何隔离arm设备上的故障?

How to isolate a fault on arm device?

我在 Arm 设备上使用 rapidjson 时出现奇怪的行为,运行 这段代码。

    #include <document.h>
    using namespace std;

int main()
{
    const char json []="[{\"Type\":\"float\",\"val_param\" : 12.025 }]";

    rapidjson::Document d;

    if( d.Parse<0>( json ).HasParseError() ) {
     //ErrorCase
    }else{
        rapidjson:: Value& val_param    = d[0]["val_param"];
        double tmp_double1  = val_param.GetDouble(); 
        cout << tmp_double1 <<endl; // -9.2559641157289301e+61 instead of 12.025
    }

    return 0;
}

在对这个问题投反对票之前。您还需要什么信息?我真的不知道如何隔离这个故障。如果是嵌入式设备导致的,或者rapidjson。以及如何解决。

==========================更新================== ======================

什么是设备? http://www.keith-koep.com/de/produkte/produkte-trizeps/trizeps-iv-m-eigenschaften/

它有硬件FPU吗?它是 ARMv5,所以我不这么认为。

您使用的是什么编译器和库(版本 numbers/specific 构建)? 您将哪些选项传递给编译器和链接器?

arm-linux-gnueabi-g++ -march=armv5te -marm -mthumb-interwork --sysroot=/usr/local/oecore-x86_64/sysroots/armv5te-linux-gnueabi

这看起来可能是 RapidJSON 中的一个未定义行为类型的错误。

由于您的目标是 ARMv5,因此您可能正在使用使用旧版 ARM FPA 格式的软件浮点库(与后来使用 IEEE754 格式的 VFP 相反)。至关重要的是,FPA 以一种奇怪的中端格式存储内容,其中 64 位双精度存储为两个小端字,但最重要的字在前。

(是的,大端 ARM 是另一个复杂的问题,但我在这里故意忽略它,因为我在任何地方都看不到 armeb-* 三元组或 -mbig-endian 选项)

将 12.025 视为 IEEE754 double:

64-bit value:             0x40280ccccccccccd.
little-endian byte order: cd cc cc cc cc 0c 28 40
as little-endian words:   0xcccccccd 0x40280ccc

现在 FPA 格式为:

as little-endian words:   0x40280ccc 0xcccccccd
byte order:               cc 0c 28 40 cd cc cc cc

尝试将其解释为纯小端 64 位值会产生 0xcccccccd40280ccc,恰好是 -9.255965e+61 的 IEEE754 表示。喜欢那个!


快速浏览一下代码,它可能更像是一个不兼容问题,而不是一个错误,因为 RapidJSON 似乎确实明确采用了浮点值的 IEEE754 格式。值得赞扬的是,尽管 the parsing code looks pretty hairy, I do see unions 而不是类型双关指针。但是,即使它不依赖于 undefined 行为,它仍然依赖于 implementation-defined 行为(浮点类型的格式),并且不幸的是,这个编译器的实现不符合预期。