map.find() 如何查看输出的程序集
How map.find() works looking at the outputted assembly
我正在调试 Android 应用程序的崩溃并遇到以下几行:
void myobject::save(std::string toSave) {
...
}
...
std::map<std::string, std::string> dict;
...
myobject::save(dict.find("username")->second);
生成的程序集:
02F05DFC bl _ZNKSt6__ndk16__treeINS_12__value_typeINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEES7_EENS_19__map_value_compareIS7_S8_NS_4lessIS7_EELb1EEENS5_IS8_EEE4findIS7_EENS_21__tree_const_iteratorIS8_PNS_11__tree_nodeIS8_PvEEiEERKT_
3096 str r6, [sp, #0x108 + var_48]
0146 mov r1, r0
CDE92E66 strd r6, r6, [sp, #0x108 + var_50]
11F81C2F ldrb r2, [r1, #0x1c]!
12F0010F tst.w r2, #0x1
06D1 bne loc_THERE
loc_FIRST:
D1E90002 ldrd r0, r2, [r1]
8968 ldr r1, [r1, #0x8]
3091 str r1, [sp, #0x108 + var_48]
CDE92E02 strd r0, r2, [sp, #0x108 + var_50]
04E0 b loc_HERE
loc_THERE:
D0E90821 ldrd r2, r1, [r0, #0x20]
2EA8 add r0, sp, #0xb8_ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcj
FDF743FD bl _ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcj
loc_HERE:
2EA9 add r1, sp, #0xb8
2046 mov r0, r4
04F047FB bl _ZN6myobject11saveENSt6__ndk112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE
我发现了错误。当 find() return 一个 end() 迭代器时发生崩溃。但是,有趣的是,崩溃发生在 new() 内部(在 basic_string::__init() 内部完成)。当 find() return 一个 end() 迭代器时,似乎 end() (end()->second) 的取消引用不会崩溃,但在将 end()->second 转换为 a 时会崩溃std::string() 就在将其传递给 myobject::save() 之前。
我试图查看 libcxx 实现,但没有找到我要找的东西。有谁知道 loc_FIRST 和 loc_THERE 这两个块的用途是什么?为什么要检查 *(r1+0x1c) == 0x1?谁能解释一下汇编代码中“->second”出现的位置?
I think it's doing a small string optimization (SSO). The loc_FIRST case would be the case where the string is contained in the SSO buffer, and just copies the 12 bytes of the string directly into the stack location for the string. The loc_THERE case is when SSO is inactive and calls std::string::__init to do the allocation and other non-SSO init work. So essentially that branch is part of the std::string construction which has been inlined into this code (but the slow non-SSO path is still out of line). The bit being checked presumably indicates whether SSO is active for that string. – BeeOnRope Mar 27 at 21:02
我正在调试 Android 应用程序的崩溃并遇到以下几行:
void myobject::save(std::string toSave) {
...
}
...
std::map<std::string, std::string> dict;
...
myobject::save(dict.find("username")->second);
生成的程序集:
02F05DFC bl _ZNKSt6__ndk16__treeINS_12__value_typeINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEES7_EENS_19__map_value_compareIS7_S8_NS_4lessIS7_EELb1EEENS5_IS8_EEE4findIS7_EENS_21__tree_const_iteratorIS8_PNS_11__tree_nodeIS8_PvEEiEERKT_
3096 str r6, [sp, #0x108 + var_48]
0146 mov r1, r0
CDE92E66 strd r6, r6, [sp, #0x108 + var_50]
11F81C2F ldrb r2, [r1, #0x1c]!
12F0010F tst.w r2, #0x1
06D1 bne loc_THERE
loc_FIRST:
D1E90002 ldrd r0, r2, [r1]
8968 ldr r1, [r1, #0x8]
3091 str r1, [sp, #0x108 + var_48]
CDE92E02 strd r0, r2, [sp, #0x108 + var_50]
04E0 b loc_HERE
loc_THERE:
D0E90821 ldrd r2, r1, [r0, #0x20]
2EA8 add r0, sp, #0xb8_ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcj
FDF743FD bl _ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEPKcj
loc_HERE:
2EA9 add r1, sp, #0xb8
2046 mov r0, r4
04F047FB bl _ZN6myobject11saveENSt6__ndk112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE
我发现了错误。当 find() return 一个 end() 迭代器时发生崩溃。但是,有趣的是,崩溃发生在 new() 内部(在 basic_string::__init() 内部完成)。当 find() return 一个 end() 迭代器时,似乎 end() (end()->second) 的取消引用不会崩溃,但在将 end()->second 转换为 a 时会崩溃std::string() 就在将其传递给 myobject::save() 之前。
我试图查看 libcxx 实现,但没有找到我要找的东西。有谁知道 loc_FIRST 和 loc_THERE 这两个块的用途是什么?为什么要检查 *(r1+0x1c) == 0x1?谁能解释一下汇编代码中“->second”出现的位置?
I think it's doing a small string optimization (SSO). The loc_FIRST case would be the case where the string is contained in the SSO buffer, and just copies the 12 bytes of the string directly into the stack location for the string. The loc_THERE case is when SSO is inactive and calls std::string::__init to do the allocation and other non-SSO init work. So essentially that branch is part of the std::string construction which has been inlined into this code (but the slow non-SSO path is still out of line). The bit being checked presumably indicates whether SSO is active for that string. – BeeOnRope Mar 27 at 21:02