Очень странный баг при конкатенации строк.
От: Аноним  
Дата: 12.10.11 14:11
Оценка:
В общем такие проблемы обычно решаются довольно быстро.
Но тут вообще в ступор встал.

В общем вылетает с эксепшином у меня вот в таком месте:


virtual bool some_member_func(std::string& a)
{
    m_some_member_string += a; //m_some_member_string - тоже std::string
    return true;
}


Исключение происходит на выделении памяти, потому что новый размер неадекватно большой (0x2dcf9d70).
Но, что самое интересное: состояние обоих переменных нормальное.

Переменная m_some_member_string (она фактически пустая):

+        std::_String_val<char,std::allocator<char> >    {_Alval={...} }    std::_String_val<char,std::allocator<char> >
        npos    0xffffffff    const unsigned int
+        _Bx    {_Buf=0x04aeef58 "" _Ptr=0x2e900000 <Bad Ptr> }    std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Bxty
        _Mysize    0x00000000    unsigned int
        _Myres    0x0000000f    unsigned int

Переменная а(в ней 16 байт записано):
+        std::_String_val<char,std::allocator<char> >    {_Alval={...} }    std::_String_val<char,std::allocator<char> >
        npos    0xffffffff    const unsigned int
+        _Bx    {_Buf=0x04aedf08 "8’™ММММММММММММ" _Ptr=0x03999238 "502 Unknown Host" }    std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Bxty
        _Mysize    0x00000010    unsigned int
        _Myres    0x0000009f    unsigned int


Что-то нелепое происходит в файле xstring line 954:


    _Myt& __CLR_OR_THIS_CALL append(const _Myt& _Right,
        size_type _Roff, size_type _Count)
        {    // append _Right [_Roff, _Roff + _Count)
        if (_Right.size() < _Roff)
            _String_base::_Xran();    // _Roff off end
        size_type _Num = _Right.size() - _Roff; //каким-то нелепым образом, в значение _Num попадает 0x2dcf9d70, хотя я ясно вижу в отладчике что _Right.size() равен 16 а _Roff = 0!!!
        if (_Num < _Count)
            _Count = _Num;    // trim _Count to size
        if (npos - _Mysize <= _Count || _Mysize + _Count < _Mysize)
            _String_base::_Xlen();    // result too long

        if (0 < _Count && _Grow(_Num = _Mysize + _Count))
            {    // make room and append new stuff
            _Traits_helper::copy_s<_Traits>(_Myptr() + _Mysize, _Myres - _Mysize,
                _Right._Myptr() + _Roff, _Count);
            _Eos(_Num);
            }
        return (*this);
        }

Обе этих переменных 100% используются только в этом потоке, никто к ним доступа не имеет.
Я сначала думал что какой-то другой поток затер в памяти эту переменную после вычисления реальной длины, но ошибка воспроизводится ровно в том же месте каждый раз.

У кого есть какие мнения как ловить багу.
Я склоняюсь все таки в сторону что кто-то херит память... но как ловить ?
Re: Очень странный баг при конкатенации строк.
От: rus blood Россия  
Дата: 12.10.11 15:16
Оценка:
Здравствуйте, Аноним, Вы писали:

Показывай, как вызывается функция, и как создается для нее аргумент.
Имею скафандр — готов путешествовать!
Re: Очень странный баг при конкатенации строк.
От: Андрей Россия  
Дата: 12.10.11 16:10
Оценка:
Здравствуйте, Аноним, Вы писали:

skip

а если сигнатуру поменять?
на some_member_func(std::string a) или хотя бы на some_member_func(const std::string& a)?
Re: Очень странный баг при конкатенации строк.
От: Ytz https://github.com/mtrempoltsev
Дата: 12.10.11 16:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>
А>virtual bool some_member_func(std::string& a)
А>{
А>    m_some_member_string += a; //m_some_member_string - тоже std::string
А>    return true;
А>}
А>


Наводящий вопрос — m_some_member_string член базового класса?
Re: Очень странный баг при конкатенации строк.
От: okman Беларусь https://searchinform.ru/
Дата: 12.10.11 17:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>У кого есть какие мнения как ловить багу.

А>Я склоняюсь все таки в сторону что кто-то херит память... но как ловить ?

Последний раз я встречал точно такую же ошибку (и тоже проявлялось на std::string) в
одной библиотеке для разбора JSON. Там в целях экономии оперативки предлагалось
пожертвовать выравниванием данных — в результате кое-где проскакивали экземпляры
строки, выравненные абы как. Точнее говоря, никак не выравненные.
В результате программа падала на строке типа std::string Str1 = Str2 + Str3.
Re: Очень странный баг при конкатенации строк.
От: ononim  
Дата: 12.10.11 20:29
Оценка:
А>У кого есть какие мнения как ловить багу.
А>Я склоняюсь все таки в сторону что кто-то херит память... но как ловить ?
Поставить break on write access (ba w в widbg) на это поле строки когда оно валидно и ждать пока его кто-нить расхерачит. Если строка конечно не меняется часто.
Как много веселых ребят, и все делают велосипед...
Re[2]: Очень странный баг при конкатенации строк.
От: kuzya_mil  
Дата: 12.10.11 21:39
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, Аноним, Вы писали:


RB>Показывай, как вызывается функция, и как создается для нее аргумент.


Не могу. Функция вызывается из другой функции та из другой и т.д.
Могу сказать только что этот код работает долго (несколько часов) и вызывается тысячи раз, после чего происходит эта шляпка.
Переменная которая передается по ссылке создается на стеке на 6 шесть вызовов вверх по стеку, и она точно целая и невредимая. В отладчике это хорошо видно.
Переменная в которую делается присваивание (переменная член) — создается вместе с экземпляром класса.
Re[2]: Очень странный баг при конкатенации строк.
От: kuzya_mil  
Дата: 12.10.11 21:42
Оценка:
Здравствуйте, Андрей, Вы писали:

А>Здравствуйте, Аноним, Вы писали:


А>skip


А>а если сигнатуру поменять?

А>на some_member_func(std::string a) или хотя бы на some_member_func(const std::string& a)?

А смысл? Вы хотите сказать что строки которые передаются по ссылке нельзя конкатенировать ?
Я не совсем уловил ход Ваших мыслей...
Re[2]: Очень странный баг при конкатенации строк.
От: kuzya_mil  
Дата: 12.10.11 21:44
Оценка:
Здравствуйте, Ytz, Вы писали:

Ytz>Здравствуйте, Аноним, Вы писали:


А>>
А>>virtual bool some_member_func(std::string& a)
А>>{
А>>    m_some_member_string += a; //m_some_member_string - тоже std::string
А>>    return true;
А>>}
А>>


Ytz>Наводящий вопрос — m_some_member_string член базового класса?

Нет. Хотя базовый класс есть, но m_some_member_string объявлен пиватом именно в этом классе в котором и делается вызов.
Re[2]: Очень странный баг при конкатенации строк.
От: kuzya_mil  
Дата: 12.10.11 21:48
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, Аноним, Вы писали:


А>>У кого есть какие мнения как ловить багу.

А>>Я склоняюсь все таки в сторону что кто-то херит память... но как ловить ?

O>Последний раз я встречал точно такую же ошибку (и тоже проявлялось на std::string) в

O>одной библиотеке для разбора JSON. Там в целях экономии оперативки предлагалось
O>пожертвовать выравниванием данных — в результате кое-где проскакивали экземпляры
O>строки, выравненные абы как. Точнее говоря, никак не выравненные.
O>В результате программа падала на строке типа std::string Str1 = Str2 + Str3.

Интересная мысль, сделаю щаз ревизию выравниваний.
Хотя с бага с выравниваниями могла бы сразу проявится по идее...
Re[2]: Очень странный баг при конкатенации строк.
От: kuzya_mil  
Дата: 12.10.11 22:03
Оценка:
Здравствуйте, ononim, Вы писали:

А>>У кого есть какие мнения как ловить багу.

А>>Я склоняюсь все таки в сторону что кто-то херит память... но как ловить ?
O>Поставить break on write access (ba w в widbg) на это поле строки когда оно валидно и ждать пока его кто-нить расхерачит. Если строка конечно не меняется часто.

Хорошая мысля!поставлю брекпоинт с кондишином, чой это(с) я сам не догадался
Re[3]: Очень странный баг при конкатенации строк.
От: Ytz https://github.com/mtrempoltsev
Дата: 13.10.11 05:17
Оценка:
Здравствуйте, kuzya_mil, Вы писали:

Ytz>>Наводящий вопрос — m_some_member_string член базового класса?

_>Нет. Хотя базовый класс есть, но m_some_member_string объявлен пиватом именно в этом классе в котором и делается вызов.

Сделай его членом базового класса и проверь все ли в порядке.
Re[3]: Очень странный баг при конкатенации строк.
От: rus blood Россия  
Дата: 13.10.11 06:15
Оценка:
Здравствуйте, kuzya_mil, Вы писали:

_>Не могу. Функция вызывается из другой функции та из другой и т.д.

_>Могу сказать только что этот код работает долго (несколько часов) и вызывается тысячи раз, после чего происходит эта шляпка.
_>Переменная которая передается по ссылке создается на стеке на 6 шесть вызовов вверх по стеку, и она точно целая и невредимая. В отладчике это хорошо видно.
_>Переменная в которую делается присваивание (переменная член) — создается вместе с экземпляром класса.

Отладчик может показывать что угодно, примеры тут уже были.
Неплохо пройтись отладчиком по ассемблерному коду, с проверка значений регистров и памяти.

Также, проверься на переполнение стека.
Имею скафандр — готов путешествовать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.