Когда все пишут плохой код…

October 21st, 2009 Begemot Posted in Программирование

…получается неприятная хрень и приходиться долго отлаживать.

Наткнулся на интересную багу, как раз перед выпуском новой версии – программа падает при выходе. После утра с дебагером, я конечно это победил, но случай интересный. Как я понимаю проблема в совокупности – плохого кода в databaselayer’e, плохого архитектурного решения и небезопасного подхода у меня и ошибки в самой wxWidgets. (disclamer : все выпады против чужого кода, основываются на сугубо субъективных догадках). По отдельности все это в принципе не критично, ну разве кроме ошибки в вх, но раз ее никто еще не обнаружил, видимо нужна редкая комбинация факторов что бы она проявилась, но сойдясь в одном проекте – приводило к падению. Итак

Мои проблемы

Две ошибки – я использовал глобальную переменную объект своего класса, для взаимодействия с базой данных. Все просто открываем, владеем и работаем с базой данных, деструктор разумеется ее закрывает. Раз деструктор все закрывает, то зачем закрывать руками при выходе? Думал я так раньше.

databaselayer

Есть там такой, имхо не очень красивый код

void DatabaseErrorReporter::ResetErrorCodes()
{
   m_strErrorMessage = _("");

   m_nErrorCode = DATABASE_LAYER_OK;
}

и вызывается он и их процедуры закрытия. Вот если бы там было написано грамотно,

   m_strErrorMessage = wxEmptyString;  
  //   m_strErrorMessage = _wxT("");  или так

то проблем не было бы.

 

wxWidgets trunk

Ну и похоже есть проблема в самой wx, в логике в e:\Const\wxWidgets-trunk\src\common\strconv.cpp. Там две процедуры забавно вызывают друг друга в цикле

    Flashnote.exe!wxMBConv::ToWChar(wchar_t * dst=0x00000000, unsigned int dstLen=0, const char * src=0x00a1414b, unsigned int srcLen=4294967295)  Строка 161 + 0x14 байт C++
    Flashnote.exe!wxMBConv::MB2WC(wchar_t * outBuff=0x00000000, const char * inBuff=0x00a1414b, unsigned int outLen=0)  Строка 357 + 0x1c байт    C++
    Flashnote.exe!wxMBConv::ToWChar(wchar_t * dst=0x00000000, unsigned int dstLen=0, const char * src=0x00a1414b, unsigned int srcLen=4294967295)  Строка 230 + 0x17 байт C++
    Flashnote.exe!wxMBConv::MB2WC(wchar_t * outBuff=0x00000000, const char * inBuff=0x00a1414b, unsigned int outLen=0)  Строка 357 + 0x1c байт    C++
    Flashnote.exe!wxMBConv::ToWChar(wchar_t * dst=0x00000000, unsigned int dstLen=0, const char * src=0x00a1414b, unsigned int srcLen=4294967295)  Строка 230 + 0x17 байт C++
    Flashnote.exe!wxMBConv::MB2WC(wchar_t * outBuff=0x00000000, const char * inBuff=0x00a1414b, unsigned int outLen=0)  Строка 357 + 0x1c байт    C++
    Flashnote.exe!wxMBConv::ToWChar(wchar_t * dst=0x00000000, unsigned int dstLen=0, const char * src=0x00a1414b, unsigned int srcLen=4294967295)  Строка 230 + 0x17 байт C++

Хорошо все-таки использовать  open source библиотеки, всегда можно пойти и посмотреть в чем затык.  И теперь когда я победил эту проблему, я могу спокойно релизить свой notes manager повышая свой внутренний статус wxWidgets 3.0 до использования в продакшене:)

 

p.s. надо не забыть в багтрекер закинуть описание бага.

Related:

12 Responses to “Когда все пишут плохой код…”

  1. Ужас какой-то. Если в пути к файлу помощи встречаются русские символы wxHtmlHelpController не показывает справку.

    С винчестера всё работало как надо (папка латинская), но когда перенес программу на флешку – хелп пропал. Сначала думал глюк в программе, потом выяснилось, что проблема в русском названии папки с программой. Стоит переименовать папку – хелп волшебным образом показывается. Что теперь делать…

  2. Причем в Windows открывается пустой хелп, а под Ubuntu программа умирает при попытке выполнения
    HelpController()->AddBook( GetHelpFile() );

  3. Как минимум сабмитить баг, как максимум – дебажить и сабмитить патч:)

  4. gdb 6.7 начисто отказывается отлаживать программу в папке с русским названием, а иначе ошибку воспроизвести невозможно

  5. а хелп можно запускать только из папки с программой?:)

  6. в портабельной версии все лежит в одной папке 🙂 ну и не хотелось бы, чтобы пользователь, поставивший программу не в папку по умолчанию получил фигу.

    путем хитрых манипуляций запустил отладку и добрался до функции
    wxString wxFileSystem::FindFirst(const wxString& spec, int flags)
    отдебажить которую так и не смог – gdb умирает и убивает code::blocks

    что же это такое творится…

  7. Основная проблема в том, что у меня плохо как с отладкой так и с английским. немцы мы…

  8. Сергей: в портабельной версии все лежит в одной папке ну и не хотелось бы, чтобы пользователь, поставивший программу не в папку по умолчанию получил фигу.

    Причем тут пользователь? для отладки то ты можешь собрать себе любую конфигурацию, хоть C:\хелп хоть AppPath\Хелп

    Почему gdb под виндой же тоже есть проблема? дебажь чем-то нормальным под виндой.
    Ну или проще – берешь стандартный пример, компиляешь. ставишь его в условия когда есть русские буквы в пути, если бага есть – идешь пишешь баг.

  9. Begemot: Ну или проще – берешь стандартный пример, компиляешь. ставишь его в условия когда есть русские буквы в пути, если бага есть – идешь пишешь баг.

    ага, так я сделал. пока до FindFirst добрался. копаю дальше. посмотрим как в OS X с этим обстоит дело

  10. Уже давно есть gdb 6.8-3 там проблема с русским решена

  11. Boris: Уже давно есть gdb 6.8-3 там проблема с русским решена

    решил отдебажить в Убунту, там проще. у меня такое смутное ощущение, что в виджетах сильно напортачили со стоками. В Мас OS X даже даже добавление каталога в локаль вызывает крах

  12. wxURI::Unescape( L”что_то_по_русски”) вот где все порылось!
    не работает оно с русскими буквами