使用C ++和Android NDK解析包含字符串的protobuf消息时崩溃 [英] Crash when parsing protobuf message containing a string using C++ and Android NDK
问题描述
我有两个程序,都运行在一个Android 2.3.4平台上 - 一个是一个C ++二进制程序的守护进程形式,用cmake编译,另一个是一个apk与jni部分编译ndk-build。我使用android-ndk-r6。我使用protobuf消息和本地unix套接字在他们之间传递数据。我使用SerializeAsString和ParseFromString方法。
这是一个代码片段
I have two programs, both running on an Android 2.3.4 platform - one is a C++ binary in a daemon form, compiled with cmake, the other is a apk with jni part compiled with ndk-build. I'm using android-ndk-r6. I'm using protobuf messages and local unix sockets to pass data between them. I'm using the SerializeAsString and ParseFromString methods. Here is a snippet
AbstractMessage protobuff_msg;
protobuff_msg.set_id ( 1 ); //TODO: for now hardcoded, later can be used for request-response pairs
protobuff_msg.set_type ( AbstractMessage_MessageType_REQUEST );
protobuff_msg.set_method ( AbstractMessage_MethodName_LOAD_DEFINITION );
AbstractMessage_Parameter* param = protobuff_msg.mutable_param()->Add();
param->set_name(AbstractMessage_ParameterName_FILEPATH);
param->set_value(filepath);
std::string msg = protobuff_msg.SerializeAsString();
client_->write_protobuf_message ( msg, MAGIC_NUMBER );
AbstractMessage是protobuf消息,
AbstractMessage_MessageType_REQUEST,LOAD_DEFINITION,FILEPATH是枚举,AbstractMessage_Parameter是一个重复嵌套消息。 param值是一个字符串,所有其他类型都是int。客户端是用于套接字通信的自定义库。
AbstractMessage is the protobuf message, AbstractMessage_MessageType_REQUEST,LOAD_DEFINITION,FILEPATH are enums, AbstractMessage_Parameter is a repeated nested message. The param value is a string, all other types are int-s. client is a custom library for the socket communication.
int Foo::write_protobuf_message(std::string protobuf_msg, int magic_number)
{
int send_int = 0;
send_int = htonl(magic_number);
int n = write_to_socket((void *)&send_int, sizeof(int));
if(n<0)
return -1;
send_int = htonl(protobuf_msg.size());
n = write_to_socket((void *)&send_int, sizeof(int));
if(n<0)
return -1;
n = write_to_socket((void *)protobuf_msg.c_str(),protobuf_msg.size());
return n;
}
The parsing:
void foo ( void* buffer, int buff_size, int error)
{
std::string buffstr;
if (error == 0)
{
buffstr.assign ( ( char* ) buffer, buff_size );
AbstractMessage proto_msg;
bool res = proto_msg.ParsePartialFromString(buffstr);
if (res)
{
//TODO handle ok parsing
return;
}
else
{
//TODO handle failed parsing
return;
}
}
}
用两个c ++守护程序二进制文件作为测试工具进行测试,并且它工作。然而,当我尝试真正的交易apk,我得到以下崩溃:
This scenario is tested with two c++ daemon binaries as test tools and it works. However when I try the real deal with the apk I get the following crash:
09-30 11:43:28.335: INFO/DEBUG(1044): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
09-30 11:43:28.335: INFO/DEBUG(1044): Build fingerprint: 'foobar/voles/sholes/sholes:2.2.1/FRG83D/75603:user/release-keys'
09-30 11:43:28.335: INFO/DEBUG(1044): pid: 3991, tid: 4001 >>> com.foo.bar <<<
09-30 11:43:28.335: INFO/DEBUG(1044): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
09-30 11:43:28.335: INFO/DEBUG(1044): r0 00000027 r1 deadbaad r2 a0000000 r3 00000000
09-30 11:43:28.335: INFO/DEBUG(1044): r4 00000001 r5 00000000 r6 80422d0c r7 0000a000
09-30 11:43:28.342: INFO/DEBUG(1044): r8 44156eb0 r9 44156eb4 10 000ab44c fp 000001f0
09-30 11:43:28.342: INFO/DEBUG(1044): ip afd46668 sp 44156c80 lr afd193b1 pc afd15e80 cpsr 60000030
09-30 11:43:28.342: INFO/DEBUG(1044): d0 6472656767756265 d1 696e6a2f6c6c6173
09-30 11:43:28.342: INFO/DEBUG(1044): d2 4194fc184194fb65 d3 4194fc804194fc74
09-30 11:43:28.342: INFO/DEBUG(1044): d4 4194fce84194fcb4 d5 4194fd504194fd1c
09-30 11:43:28.342: INFO/DEBUG(1044): d6 4194fdb84194fd84 d7 4194fe204194fdec
09-30 11:43:28.342: INFO/DEBUG(1044): d8 0000000000000000 d9 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044): d10 0000000000000000 d11 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044): d12 0000000000000000 d13 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044): d14 0000000000000000 d15 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044): d16 00000000405122d8 d17 3fe999999999999a
09-30 11:43:28.350: INFO/DEBUG(1044): d18 42eccefa43de3400 d19 3fbc71c71c71c71c
09-30 11:43:28.350: INFO/DEBUG(1044): d20 4008000000000000 d21 3fd99a27ad32ddf5
09-30 11:43:28.350: INFO/DEBUG(1044): d22 3fd24998d6307188 d23 3fcc7288e957b53b
09-30 11:43:28.350: INFO/DEBUG(1044): d24 3fc74721cad6b0ed d25 3fc39a09d078c69f
09-30 11:43:28.350: INFO/DEBUG(1044): d26 0000000000000000 d27 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044): d28 0000000000000000 d29 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044): d30 0000000000000000 d31 0000000000000000
09-30 11:43:28.350: INFO/DEBUG(1044): scr 60000010
09-30 11:43:28.514: INFO/DEBUG(1044): #00 pc 00015e80 /system/lib/libc.so (__libc_android_abort)
09-30 11:43:28.514: INFO/DEBUG(1044): #01 pc 00013834 /system/lib/libc.so (dlfree)
09-30 11:43:28.514: INFO/DEBUG(1044): #02 pc 00014726 /system/lib/libc.so (free)
09-30 11:43:28.514: INFO/DEBUG(1044): code around pc:
09-30 11:43:28.514: INFO/DEBUG(1044): afd15e60 2c006824 e028d1fb b13368db c064f8df
09-30 11:43:28.514: INFO/DEBUG(1044): afd15e70 44fc2401 4000f8cc 49124798 25002027
09-30 11:43:28.514: INFO/DEBUG(1044): afd15e80 f7f57008 2106ebce ed7af7f6 460aa901
09-30 11:43:28.514: INFO/DEBUG(1044): afd15e90 f04f2006 95015380 95029303 e8a0f7f6
09-30 11:43:28.514: INFO/DEBUG(1044): afd15ea0 462aa905 f7f62002 f7f5e8ac 2106ebba
09-30 11:43:28.514: INFO/DEBUG(1044): code around lr:
09-30 11:43:28.514: INFO/DEBUG(1044): afd19390 4a0e4b0d e92d447b 589c41f0 26004680
09-30 11:43:28.514: INFO/DEBUG(1044): afd193a0 686768a5 f9b5e006 b113300c 47c04628
09-30 11:43:28.514: INFO/DEBUG(1044): afd193b0 35544306 37fff117 6824d5f5 d1ef2c00
09-30 11:43:28.514: INFO/DEBUG(1044): afd193c0 e8bd4630 bf0081f0 0002816c ffffff88
09-30 11:43:28.522: INFO/DEBUG(1044): afd193d0 b086b570 f602fb01 9004460c a804a901
09-30 11:43:28.522: INFO/DEBUG(1044): stack:
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c40 afd42664
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c44 000a9908
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c48 00000015
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c4c afd18479 /system/lib/libc.so
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c50 afd4270c
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c54 afd426b8
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c58 00000000
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c5c afd193b1 /system/lib/libc.so
09-30 11:43:28.522: INFO/DEBUG(1044): 44156c60 00000001
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c64 44156c94
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c68 80422d0c
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c6c 0000a000
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c70 44156eb0
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c74 afd186d3 /system/lib/libc.so
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c78 df002777
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c7c e3a070ad
09-30 11:43:28.530: INFO/DEBUG(1044): #00 44156c80 00000023
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c84 001533b8
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c88 80422d0c
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c8c 44156cec
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c90 80422d0c
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c94 fffffbdf
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c98 44156eb0
09-30 11:43:28.530: INFO/DEBUG(1044): 44156c9c afd46450
09-30 11:43:28.530: INFO/DEBUG(1044): 44156ca0 44156cec
09-30 11:43:28.530: INFO/DEBUG(1044): 44156ca4 afd13839 /system/lib/libc.so
09-30 11:43:28.530: INFO/DEBUG(1044): #01 44156ca8 80422d0c
09-30 11:43:28.530: INFO/DEBUG(1044): 44156cac 44156cec
09-30 11:43:28.538: INFO/DEBUG(1044): 44156cb0 0000000b
09-30 11:43:28.538: INFO/DEBUG(1044): 44156cb4 00000000
09-30 11:43:28.538: INFO/DEBUG(1044): 44156cb8 44156eb0
09-30 11:43:28.538: INFO/DEBUG(1044): 44156cbc afd14729 /system/lib/libc.so
09-30 11:43:30.382: INFO/BootReceiver(1185): Copying /data/tombstones/tombstone_00 to DropBox (SYSTEM_TOMBSTONE)
如果我尝试只解析int protobuf消息是没有字符串/字节)都工作伟大。如果我添加字符串/字节都失败。我也试过require和optional字符串,也用字节。没有什么工作。我发现这样的崩溃我是由一个断言造成的。
任何想法?
If I try to parse only ints (I change the protobuf message to be without a string/bytes) all works great. If i add the string/bytes all fails. I tried also with required and optional string, also with bytes. Nothing works. I found that such a crash my be caused by an assert. Any ideas?
推荐答案
我可以说的错误:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad
deadbaad通常意味着无效的地址..所以你很可能在解析部分有一个无效的地址..
deadbaad usually means invalid address.. so you most probably have an invalid address in the parsing section..
我建议启用 dalvik.vm.checkjni = true
并尝试查看您是否获得任何进一步的信息
I would suggest enabling dalvik.vm.checkjni=true
and trying to see if you get any further info
这篇关于使用C ++和Android NDK解析包含字符串的protobuf消息时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!