Re: An empty vptr in an raw object

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 23-12-2016 17:59, Sage Weil wrote:
> On Fri, 23 Dec 2016, Willem Jan Withagen wrote:
>> On 23-12-2016 17:46, Sage Weil wrote:
>>> On Fri, 23 Dec 2016, Willem Jan Withagen wrote:
>>>> On 23-12-2016 15:26, Sage Weil wrote:
>>>>> On Fri, 23 Dec 2016, Willem Jan Withagen wrote:
>>>>>> On 22-12-2016 23:01, Allen Samuels wrote:
>>>>>>> I believe I mis-read the data. What I've seen before doesn't fit this data.
>>>>>>>
>>>>>>> If it fails in unit test, it shouldn't be hard to just set a HW breakpoint on the vptr and see who the culprit is.
>>>>>>
>>>>>> Well the _raw class is properly initialised:
>>>>>> $8 = {_vptr$raw = 0x817578 <vtable for ceph::buffer::raw+16>,
>>>>>>
>>>>>> And is "upgraded" to a different class:
>>>>>> 	ceph::buffer::raw_combined
>>>>>>
>>>>>> But here is the problem...
>>>>>>
>>>>>> Hardware watchpoint 5: *0x1054048
>>>>>>
>>>>>> Old value = 8484744
>>>>>> New value = 0
>>>>>> 0x000000000049ab29 in denc_traits<unsigned long, void>::encode
>>>>>> (o=@0x10501d0: 123, p=..., f=0) at
>>>>>> /usr/srcs/Ceph/work/ceph/src/include/denc.h:228
>>>>>> 228     WRITE_INT_DENC(uint64_t, __le64);
>>>>>
>>>>> Ah, okay, this is making a bit more sense now.
>>>>>
>>>>> raw_combined is trying to be clever.  It has a static create() method to
>>>>>
>>>>> - allocate an aligned buffer of size len + sizeof(raw_combined) (with some 
>>>>> rounding up), call it *ptr
>>>>> - in-place initiailize raw_combined at ptr + len (rounded up), call it *this
>>>>> - store the the actual data at ptr
>>>>> - return the raw_combined *this
>>>>>
>>>>> It has an overloaded delete operator to free the entire allocate 
>>>>> (roughly this - len) to make this work.
>>>>>
>>>>> It sounds a bit like the write into raw_combined's data portion (ptr) is 
>>>>> clobbering vptr.  Which probably suggests we wrote too much into the 
>>>>> buffer.  Can you print the contents of the raw_combined class and the 
>>>>> appender?
>>>>
>>>> Not sure if I understand the values you'd like, but this is a first attempt:
>>>> (gdb) p p
>>>> $1 = (ceph::buffer::list::contiguous_appender &) @0x7fffffffd948: {pbl =
>>>> 0x7fffffffd978, pos = 0x105404f "", bp = {_raw = 0x1054048, _off = 0,
>>>
>>>                         ^^                         ^^
>>>
>>> Yep, pos is advancing to far and clobbering _raw (the raw_combined).
>>>
>>> Try changing that sizeof(T) * 3 to s?  I can't tell from the stack 
>>> trace below what path this is.. line 206 on master is
>>>
>>>     s.push_back("foo");
>>>
>>> which is clearly not the code you're running.
>>
>> 'mmm, the version I have is already at '*3'
> 
> I mean s/sizeof(T) * 3/s/.
> 
> It makes sense that sizeof(std::string)*3 is unrelated to the encoded 
> size.

That works....

No crash, and the map test completes oke...

So are there more locations where this would be the case.
Otherwise it it just a PR for only this file...

--WjW

> 
>>
>> template<typename T>
>> void test_denc(T v) {
>>   // estimate
>>   size_t s = 0;
>>   denc(v, s);
>>   ASSERT_NE(s, 0u);
>>
>>   // encode
>>   bufferlist bl;
>>   {
>>     auto a = bl.get_contiguous_appender(sizeof(T) * 3);
>>     denc(v, a);
>>   }
>>   ASSERT_LE(bl.length(), s);
>>
>>   // decode
>>   bl.rebuild();
>>   T out;
>>   auto bpi = bl.front().begin();
>>   denc(out, bpi);
>>   ASSERT_EQ(v, out);
>>   ASSERT_EQ(bpi.get_pos(), bl.c_str() + bl.length());
>>
>>   // test glue
>>   test_encode_decode(v);
>> }
>>
>> BTW: I'm off to home. CET = 18:00, and I still have to do my shopping
>> for the backing pies and deserts for X-mas Eve.
>> So I'll be on and off-line on irregular basis, as I guess most will be.
>>
>> Happy hollidays,
>> --WjW
>>
>>
>>>
>>> sage
>>>
>>>> _len = 72}, deep = false,
>>>>   out_of_band_offset = 0}
>>>>
>>>> I do not know how to get to the raw_combined class
>>>>
>>>> But I also found this morning that pos is actually point to 0x105404f
>>>> after adding 8 bytes of size .
>>>> So writing any value to that pointer before incrementing will clobber
>>>> vptr, since it points to 0x1054047.
>>>>
>>>> --WjW
>>>>
>>>>>
>>>>> sage
>>>>>
>>>>>
>>>>>>
>>>>>> The traceback:
>>>>>> #0  0x000000000049ab29 in denc_traits<unsigned long, void>::encode
>>>>>> (o=@0x10501d0: 123, p=..., f=0) at
>>>>>> /usr/srcs/Ceph/work/ceph/src/include/denc.h:228
>>>>>> #1  0x000000000049a7a8 in denc<unsigned long, denc_traits<unsigned long,
>>>>>> void> > (o=@0x10501d0: 123, p=..., features=0) at
>>>>>> /usr/srcs/Ceph/work/ceph/src/include/denc.h:479
>>>>>> #2  0x000000000049a6a5 in _denc_friend<foo_t const,
>>>>>> ceph::buffer::list::contiguous_appender> (v=..., p=...) at
>>>>>> /usr/srcs/Ceph/work/ceph/src/test/test_denc.cc:155
>>>>>> #3  0x000000000049a62d in foo_t::encode (this=0x10501c8, p=...) at
>>>>>> /usr/srcs/Ceph/work/ceph/src/test/test_denc.cc:152
>>>>>> #4  0x000000000049a601 in denc_traits<foo_t, void>::encode (v=...,
>>>>>> p=..., f=0) at /usr/srcs/Ceph/work/ceph/src/test/test_denc.cc:163
>>>>>> #5  0x000000000049a188 in denc<foo_t, denc_traits<foo_t, void> > (o=...,
>>>>>> p=..., features=0) at /usr/srcs/Ceph/work/ceph/src/include/denc.h:479
>>>>>> #6  0x000000000049a0ac in
>>>>>> denc_traits<std::__1::map<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> >, foo_t,
>>>>>> std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>,
>>>>>> std::__1::allocator<char> > >,
>>>>>> std::__1::allocator<std::__1::pair<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> > const, foo_t> >
>>>>>>> , void>::encode<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> > > (v=..., p=...)
>>>>>>     at /usr/srcs/Ceph/work/ceph/src/include/denc.h:1010
>>>>>> #7  0x0000000000494581 in
>>>>>> denc<std::__1::map<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> >, foo_t,
>>>>>> std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>,
>>>>>> std::__1::allocator<char> > >,
>>>>>> std::__1::allocator<std::__1::pair<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> > const, foo_t> >
>>>>>>> , denc_traits<std::__1::map<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> >, foo_t,
>>>>>> std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>,
>>>>>> std::__1::allocator<char> > >,
>>>>>> std::__1::allocator<std::__1::pair<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> > const, foo_t> >
>>>>>>> , void> > (o=..., p=..., features=0) at
>>>>>> /usr/srcs/Ceph/work/ceph/src/include/denc.h:479
>>>>>> #8  0x0000000000490fb1 in
>>>>>> test_denc<std::__1::map<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> >, foo_t,
>>>>>> std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>,
>>>>>> std::__1::allocator<char> > >,
>>>>>> std::__1::allocator<std::__1::pair<std::__1::basic_string<char,
>>>>>> std::__1::char_traits<char>, std::__1::allocator<char> > const, foo_t> >
>>>>>>>> (v=...) at /usr/srcs/Ceph/work/ceph/src/test/test_denc.cc:49
>>>>>> #9  0x00000000004904e0 in denc_map_Test::TestBody (this=0x1038030) at
>>>>>> /usr/srcs/Ceph/work/ceph/src/test/test_denc.cc:206
>>>>>>
>>>>>> (gdb) p p
>>>>>> $10 = (ceph::buffer::list::contiguous_appender &) @0x7fffffffd948: {pbl
>>>>>> = 0x7fffffffd978, pos = 0x105404f "", bp = {_raw = 0x1054048, _off = 0,
>>>>>> _len = 72}, deep = false,
>>>>>>   out_of_band_offset = 0}
>>>>>> (gdb) p *p.bp._raw
>>>>>> $17 = {_vptr$raw = 0x0, data = 0x1054000 "\003", len = 72, nref = {val =
>>>>>> 1}, crc_spinlock = 0, crc_map = {__tree_ = {__begin_node_ = 0x1054078,
>>>>>>       __pair1_ =
>>>>>> {<std::__1::__libcpp_compressed_pair_imp<std::__1::__tree_end_node<std::__1::__tree_node_base<void*>*>,
>>>>>> std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<std::__1::pair<unsigned
>>>>>> long, unsigned long>, std::__1::pair<unsigned int, unsigned int> >,
>>>>>> void*> >, 2>> =
>>>>>> {<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<std::__1::pair<unsigned
>>>>>> long, unsigned long>, std::__1::pair<unsigned int, unsigned int> >,
>>>>>> void*> >> = {<No data fields>}, __first_ = {
>>>>>>             __left_ = 0x0}}, <No data fields>},
>>>>>>       __pair3_ = {<std::__1::__libcpp_compressed_pair_imp<unsigned long,
>>>>>> std::__1::__map_value_compare<std::__1::pair<unsigned long, unsigned
>>>>>> long>, std::__1::__value_type<std::__1::pair<unsigned long, unsigned
>>>>>> long>, std::__1::pair<unsigned int, unsigned int> >,
>>>>>> std::__1::less<std::__1::pair<unsigned long, unsigned long> >, true>,
>>>>>> 2>> = {<std::__1::__map_value_compare<std::__1::pair<unsigned long,
>>>>>> unsigned long>, std::__1::__value_type<std::__1::pair<unsigned long,
>>>>>> unsigned long>, std::__1::pair<unsigned int, unsigned int> >,
>>>>>> std::__1::less<std::__1::pair<unsigned long, unsigned long> >, true>> =
>>>>>> {<std::__1::less<std::__1::pair<unsigned long, unsigned long> >> =
>>>>>> {<std::__1::binary_function<std::__1::pair<unsigned long, unsigned
>>>>>> long>, std::__1::pair<unsigned long, unsigned long>, bool>> = {<No data
>>>>>> fields>}, <No data fields>}, <No data fields>},
>>>>>>           __first_ = 0}, <No data fields>}}}}
>>>>>>
>>>>>> (gdb) disassemble
>>>>>> Dump of assembler code for function denc_traits<unsigned long,
>>>>>> void>::encode(unsigned long const&,
>>>>>> ceph::buffer::list::contiguous_appender&, unsigned long):
>>>>>>    0x000000000049aaf0 <+0>:     push   %rbp
>>>>>>    0x000000000049aaf1 <+1>:     mov    %rsp,%rbp
>>>>>>    0x000000000049aaf4 <+4>:     sub    $0x20,%rsp
>>>>>>    0x000000000049aaf8 <+8>:     mov    $0x8,%eax
>>>>>>    0x000000000049aafd <+13>:    mov    %eax,%ecx
>>>>>>    0x000000000049aaff <+15>:    mov    %rdi,-0x8(%rbp)
>>>>>>    0x000000000049ab03 <+19>:    mov    %rsi,-0x10(%rbp)
>>>>>>    0x000000000049ab07 <+23>:    mov    %rdx,-0x18(%rbp)
>>>>>>    0x000000000049ab0b <+27>:    mov    -0x8(%rbp),%rdx
>>>>>>    0x000000000049ab0f <+31>:    mov    (%rdx),%rdx
>>>>>>    0x000000000049ab12 <+34>:    mov    -0x10(%rbp),%rdi
>>>>>>    0x000000000049ab16 <+38>:    mov    %rcx,%rsi
>>>>>>    0x000000000049ab19 <+41>:    mov    %rdx,-0x20(%rbp)
>>>>>>    0x000000000049ab1d <+45>:    callq  0x49a1d0
>>>>>> <ceph::buffer::list::contiguous_appender::get_pos_add(unsigned long)>
>>>>>>    0x000000000049ab22 <+50>:    mov    -0x20(%rbp),%rcx
>>>>>>    0x000000000049ab26 <+54>:    mov    %rcx,(%rax)
>>>>>> => 0x000000000049ab29 <+57>:    add    $0x20,%rsp
>>>>>>    0x000000000049ab2d <+61>:    pop    %rbp
>>>>>>    0x000000000049ab2e <+62>:    retq
>>>>>> End of assembler dump.
>>>>>>
>>>>>> (gdb) info registers
>>>>>> rax            0x1054047        17121351
>>>>>> rbx            0x0      0
>>>>>> rcx            0x7b     123
>>>>>> rdx            0x7b     123
>>>>>> rsi            0x7fffffffd948   140737488345416
>>>>>> rdi            0x105404f        17121359
>>>>>> rbp            0x7fffffffd4f0   0x7fffffffd4f0
>>>>>> rsp            0x7fffffffd4d0   0x7fffffffd4d0
>>>>>> r8             0x0      0
>>>>>> r9             0x0      0
>>>>>> r10            0x0      0
>>>>>> r11            0x829100 8556800
>>>>>> r12            0x7fffffffe910   140737488349456
>>>>>> r13            0x7fffffffe928   140737488349480
>>>>>> r14            0x7fffffffe918   140737488349464
>>>>>> r15            0x1      1
>>>>>> rip            0x49ab29 0x49ab29 <denc_traits<unsigned long,
>>>>>> void>::encode(unsigned long const&,
>>>>>> ceph::buffer::list::contiguous_appender&, unsigned long)+57>
>>>>>>
>>>>>> And this is wierd:
>>>>>> 	%rax contains  0x1054047
>>>>>> 	_raw is  0x1054048
>>>>>>
>>>>>> So writing %rcx to (%rax) is definitly going to overwrite the larger
>>>>>> part of _raw.
>>>>>>
>>>>>> So now the question transforms into:
>>>>>>     Why does %rax hold this wierd value ??
>>>>>>     or Why does get_pos_add(sizeof(etype)) a negative offset ??
>>>>>>
>>>>>> Got to go and do real dayjob work.
>>>>>>
>>>>>> --WjW
>>>>>> --
>>>>>> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
>>>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>>>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>>>
>>>>>>
>>>>
>>>> --
>>>> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
>>>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>>
>>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
>>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
>> the body of a message to majordomo@xxxxxxxxxxxxxxx
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>>

--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux