为什么全局声明此变量会导致段错误?

时间:2016-12-02 08:00:00

标签: android c++ x86 segmentation-fault

让我们比较一下我所拥有的单元测试的两个版本:

const VersionVector kTestVers {"2@*,3@$,1@bob"_sl}; // Adding 'static' does not help
const VersionVector kTestCASVers {"3@$,2@*"_sl};

static void a() {
   // verify something with these two things
}

static void b() {
   // create something with these two things
}

static void a() {
   const VersionVector kTestVers {"2@*,3@$,1@bob"_sl};
   const VersionVector kTestCASVers {"3@$,2@*"_sl};
   // verify something with these two things
}

static void b() {
   const VersionVector kTestVers {"2@*,3@$,1@bob"_sl};
   const VersionVector kTestCASVers {"3@$,2@*"_sl};
   // create something with these two things
}

我正在使用我的Nexus 5(armeabi-v7a),并决定了解它如何在Genymotion VM(x86)中使用。这两个都可以在设备上正常工作,但在VM上,第一个版本会立即进行段错误,而第二个版本可以正常运行。 segfault的堆栈跟踪显示故障发生在全局变量的初始化期间:

  

#00 pc 00114e7f / data / local / tmp / LiteCore / CppTests(litecore :: VersionVector :: VersionVector(fleece :: slice)+207)
   #01 pc 00010b48 / data / local / tmp / LiteCore / CppTests(_GLOBAL__sub_I_RevisionTest.cc + 104)
   #02 pc 00003203 / system / bin / linker(__ dl__ZN6soinfo17call_constructorsEv.part.140 + 1055)
   #03 pc 0000ddbe / system / bin / linker(__ dl ___ linker_init + 4558)
   #04 pc 00010c17 / system / bin / linker(__ dl__start + 29)
   #05 pc 00000001<未知>

VersionVector有三个成员变量,其中一个是std::vector<Version>。导致段错误的违规行是push_back对象的Version,构造为构造函数的一部分:

VersionVector::VersionVector(slice string)
:_string(string)
{
    if (string.size == 0 || string.findByte('\0'))
        error::_throw(error::BadVersionVector);

    while (string.size > 0) {
        const void *comma = string.findByte(',');
        if (comma == nullptr) {
            comma = string.end();
        }
        _vers.push_back( Version(string.upTo(comma), false) ); // This line causes the segfault, and constructing the object separately does not help
        string = string.from(comma);
        if (string.size > 0)
            string.moveStart(1); // skip comma
    }
}

这里是否存在一些未定义的行为?

编辑:其他defs

class Version {
public:
    // Methods and one static const size_t...
private:
    friend class VersionVector;
    peerID      _author; //peerID is typedef'd to slice
    generation  _gen {0};  //generation is typedef'd to uint64_t
}

struct slice {
    const void* buf;
    size_t size;

    // Methods...
}

此外,整个回购都在Github上。 Here是包含单元测试的文件,文件with VersionVector and Version和文件with slice

编辑一些新信息:

_authorVersion字段的存在会影响到这一点。在最简单的形式中,我可以想到我已将其归结为:

#include "VersionVector.hh"
#include "slice.hh"
using namespace fleece;
using namespace litecore;

const VersionVector kTestVers {"2@*,3@$,1@bob"_sl};
const VersionVector kTestCASVers {"3@$,2@*"_sl};

int main()
{
}

这也导致了段错误。除了上面涉及的内容之外,我注释掉了所有内容,并且只编译了Fleece静态库(具有slice)和VersionVector.cc以及上面的main.cpp。如果我注释掉_author字段,那么不再有段错误,即使我没有把它分配给任何东西,只要把它留在课堂上,我就会得到段错误。

0 个答案:

没有答案