2016-05-27 10 views
0

protobufを使用して動的作成メッセージに関する奇妙な問題を抱えています。コードは以下のように、エラーなく動作します。しかし、私は次のように主な機能をコメントアウトする場合:protobufコアダンプ機能で動的生成メッセージをラップする場合

​​

それはコア!主に異なるのは、関数内のメッセージの作成のみをラップしているようです。呼び出しスタックを検索するとき:

(gdb) where 
    #0 0x0000000001436ed0 in ??() 
    #1 0x00007ff218c8f0e3 in google::protobuf::internal::ReflectionOps::Clear (message=0x1437aa0) 
at google/protobuf/reflection_ops.cc:133 
    #2 0x00007ff218c3328b in InlineParseFromCodedStream (message=0x1437aa0, input=0x7ffc82fc3aa0) 
at google/protobuf/message_lite.cc:131 
    #3 InlineParseFromArray (message=0x1437aa0, size=<optimized out>, data=<optimized out>) 
at google/protobuf/message_lite.cc:143 
    #4 google::protobuf::MessageLite::ParseFromArray (this=0x1437aa0, data=<optimized out>, 
size=<optimized out>) at google/protobuf/message_lite.cc:207 
    #5 0x000000000040137e in parse_msg (p_msg=0x1437aa0, 
buf=0x7ffc82fc3dc0 "\b\237\215\006\022\024QT-SIM-504761089-101", len=26) at pb_test.cpp:46 
    #6 0x000000000040172d in main (argc=1, argv=0x7ffc82fc42c8) at pb_test.cpp:95 
    (gdb) fr 1 
    #1 0x00007ff218c8f0e3 in google::protobuf::internal::ReflectionOps::Clear (message=0x1437aa0) 
at google/protobuf/reflection_ops.cc:133 
    133 reflection->ListFields(*message, &fields); 
    (gdb) p reflection->ListFields 
    Cannot take address of method ListFields. 

ListFieldsはNull(純粋仮想関数呼び出し)のようです。誰が私になぜこれが起こるのかを知る手伝いをすることができますか?関数で作成をラップするときにコードが機能しないのはなぜですか?前もって感謝します!ファイルtest.protoで

message SvrRegRsp{  
    required int32 RetCode = 1; 
    required string SID = 2; 
} 

のcppファイル:factory.GetPrototype(desc);message->New();

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#include <unistd.h> 

#include <string> 

#include <google/protobuf/descriptor.pb.h> 
#include <google/protobuf/dynamic_message.h> 
#include <google/protobuf/compiler/importer.h> 

using namespace google::protobuf; 
using namespace google::protobuf::compiler; 

enum { 
    MAX_PACKET_LEN = 1024, 
}; 

int gen_msg(Importer* pb, char* buf, int* len) 
{ 
    const Descriptor* desc = pb->pool()->FindMessageTypeByName("SvrRegRsp"); 
    DynamicMessageFactory factory; 
    const Message *message = factory.GetPrototype(desc); 
    Message *p_msg = message->New(); 
    const Reflection *reflection = p_msg->GetReflection(); 

    const FieldDescriptor *field = desc->field(1); 
    reflection->SetString(p_msg, field, "QT-SIM-504761089-101"); 

    field = desc->field(0); 
    reflection->SetInt32(p_msg, field, 99999); 

    p_msg->SerializeToArray(buf, *len) ; 
    *len = p_msg->ByteSize(); 

    std::string s = p_msg->DebugString(); 
    printf("req: %s\nsize: %d\n", s.c_str(), *len); 

    return 0; 
} 

int parse_msg(Message* p_msg, const char* buf, int len) 
{ 
    if(p_msg) { 
     p_msg->ParseFromArray(buf, len); // core here, because p_msg vptr is NULL. 

     std::string s = p_msg->DebugString(); 
     printf("rsp2:\n%s\nsize: %d\n", s.c_str(), len); 
    } 

    return 0; 
} 

Message* get_msg(Importer* pb) 
{ 
    const Descriptor* desc = pb->pool()->FindMessageTypeByName("SvrRegRsp"); 

    DynamicMessageFactory factory; 
    const Message *message = factory.GetPrototype(desc); 
    Message *p_msg = message->New(); 
    return p_msg; 
} 


int main(int argc, char** argv) 
{ 
    char cwd[256] = {0}; 
    getcwd(cwd, sizeof(cwd)); 

    printf("cwd: %s\n", cwd); 

    DiskSourceTree disk; 
    disk.MapPath("", cwd); 
    Importer pb(&disk, NULL); 

    const FileDescriptor* file_desc = pb.Import("test.proto"); 
    if(!file_desc) { 
     return -1; 
    } 

    char packet[MAX_PACKET_LEN] = {0}; 
    int len = MAX_PACKET_LEN; 

    gen_msg(&pb, packet, &len); 

//#if 0 
    const Descriptor* desc = pb.pool()->FindMessageTypeByName("SvrRegRsp"); 
    DynamicMessageFactory factory; 
    const Message *message = factory.GetPrototype(desc); 
    Message *p_msg = message->New(); 
//#endif 
// Message* p_msg = get_msg(&pb); 

    parse_msg(p_msg, packet, len); 

    return 0; 
} 

答えて

0

チェック生成されたコードに戻ったとき、彼らはポインタを保持し、リリースされていない場合
その後、工場が範囲外になると、それらは破壊されており、あなたはぶら下がっているポインタにアクセスしています。

+0

はい、「DynamicMessageFactory」は、それと共に作成されたすべてのメッセージよりも長く存続する必要があります。 –

関連する問題