【发布时间】:2015-09-23 12:47:38
【问题描述】:
我正在使用 Rapidjson,并注意到当我在 g++ (-O1/-O2/-O3) 中打开优化时,我遇到了分段错误。我想我已经追踪到了 rapidjson 中的 GenericValue& AddMember() 函数。
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
RAPIDJSON_ASSERT(IsObject());
RAPIDJSON_ASSERT(name.IsString());
Object& o = data_.o;
if (o.size >= o.capacity) {
if (o.capacity == 0) {
o.capacity = kDefaultObjectCapacity;
o.members = reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member)));
}
else {
SizeType oldCapacity = o.capacity;
o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
o.members = reinterpret_cast<Member*>(allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)));
}
}
o.members[o.size].name.RawAssign(name);
o.members[o.size].value.RawAssign(value);
o.size++;
return *this;
}
调试时,我可以看到 kDefaultObjectCapacity ( 正在被优化出来(这是一个静态的 const SizeType kDefaultObjectCapacity = 16)
因此行“o.capacity = kDefaultObjectCapacity;”没有被执行,并且 malloc 正在分配 0 字节然后尝试强制转换它。
为什么要删除这个静态常量?
我尝试过让 Object& o 既易变又静态,但均未奏效。 有什么想法吗?
谢谢 会
编辑: 我不能轻易地在嵌入式平台上运行测试,rapidjson 目前是使用 buildroot 构建的。我尝试了单元测试,但无法让它们达到目标。
我可以看看提供程序集,但它是大型应用程序的一部分,因此可能很难找到合适的位。
对于信息,这是调用 rapidjson 代码的方法,这似乎是问题所在:
int16_t FrontEndJSONHandlers::get_run_cfg_packer(JSONEngine& json_engine, char *message, int32_t *length)
{
Document doc;
// Need to pack an empty request to get the data
doc.SetObject();
doc.AddMember(JSONRPC_MEMBER, JSONRPC_VERSION, doc.GetAllocator());
doc.AddMember(METHOD_MEMBER, JSON_RPC_METH_GET_RUN_CFG, doc.GetAllocator());
doc.AddMember(ID_MEMBER, json_engine.GetNextMessageID(), doc.GetAllocator());
// Format the message
json_engine.FormatMessageAndRegisterResponseHandler(&doc, &message, &length, get_run_cfg_handler);
return 0;
}
如果我将 Document doc 设为静态,它不会出现段错误 - 但不确定这是否是最好的解决方法?
【问题讨论】:
-
你能告诉我们生成的程序集,包括优化和不优化吗? (见stackoverflow.com/questions/137038/…)
-
rapidjson 包中的单元测试是否通过?可能是应用程序在某处损坏了内存。
标签: c++ c segmentation-fault compiler-optimization rapidjson