如何隔离手臂设备的故障

How to isolate a fault on arm device?

本文关键字:故障 何隔离 隔离      更新时间:2023-10-16

我在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,所以我不这么认为。

你使用什么编译器和库(版本号/特定构建)?你传递给编译器和链接器的选项是什么?

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双精度:

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表示。真想不到!


快速浏览一下代码,严格来说,这可能是一个不兼容而不是一个bug,因为RapidJSON似乎明确地假设浮点值的IEEE754格式。值得赞扬的是,尽管解析代码看起来相当复杂,但我确实看到了联合而不是类型双关语指针。然而,即使它不依赖于未定义的行为,它仍然依赖于实现定义的行为(浮点类型的格式),不幸的是,这个编译器的实现不符合预期。