-1

私は 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 ( が最適化されていることがわかります (これは static const SizeType kDefaultObjectCapacity = 16 です)

したがって、「o.capacity = kDefaultObjectCapacity;」という行 は実行されておらず、malloc は 0 バイトを malloc してからキャストしようとしています。

この static const が削除されるのはなぜですか?

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 を static にすると、セグ フォールトは発生しません。

4

2 に答える 2

1

GCC 4.9 でコンパイルすると、同様の問題が発生しました。最適化フラグが指定されている (-On) と、セグメンテーション違反が発生します。複製するのは非常に簡単です。コードは次のとおりです。

//...
#include "extern/rapidjson/document.h"
//...
void* MyThread(void*)
{
   std::cout << "Start of MyThread" << std::endl;

   rapidjson::Document doc;
   doc.Parse("{ \"NAME\": \"Peter\", \"AGE\": 38, \"Male\": true}");

   std::cout << "End!";

   return NULL;
}

int main(int argc, char** argv) 
{
   pthread_t thread;

   pthread_create(&thread, NULL, &MyThread, NULL);

   std::string str;
   std::cout << "Press <Return>"  << std::endl;
   std::getline(std::cin, str);

   return 0;
 }

ここで重要なのは、別のスレッドで作成および解析されるドキュメントです。main() で直接 "MyThread(NULL)" を呼び出すと、バグは発生しません。

最適化された Visual Studio 2012 の同様のコードは正常に動作します。VS コード分析を実行しましたが、エラーは見つかりませんでした。唯一の違いはスレッドです。

std::thread th([] { MyThread(NULL); }); 
th.join();

===============================================

この問題は、バージョン 1.0.2 以降で修正されています。最新のコードを使用すると問題なく動作します。

于 2016-02-16T01:45:34.550 に答える