Маленькая история о том, как я переустанавливал ОС из-за libexpat, или как не стоит обрабатывать ошибки

Альтернативный заголовок: «В любой непонятной ситуации возвращай Out of memory».

Давеча решил я запустить свой самописный сервер веселья ради, как я делал это тысячу раз до этого, и каково же было моё удивление, когда я внезапно увидел следующую строчку в консоли: Error when parsing «example_proj.xml»: 1:0 out of memory.

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

Итак. Out of memory? На XML в 50 строчек? Сказать, что я был ошарашен — это не сказать ничего. «Но ведь раньше всё работало». Ни код сервера, ни так называемый LibCustomConfig никак не менялись.

Будучи абсолютно сбитым с толку я решил свалить всю вину на последнее обновление последней Ubuntu, после которого проблема и появилась. А вместе с ней появились и другие проблемы: падения и подвисания разных приложений, как будто сам Chaos Monkey дотянулся до меня своими лапами. Может где-то в недрах поломался ABI?

Пересаживаюсь на свежую LTS версию Ubuntu, пересобираю сервер и… опять out of memory.

Пришло время расчехлять GDB. Кто-то скажет, что с этого и надо было начать, но дебажить сторонние либы очень не хотелось.

LibCustomConfig использует libexpat примерно так:

Parser::Parser(/*...,*/ char separator = ':')
{ if (separator) /* Constructs a new parser and namespace processor. Element type names and attribute names that belong to a namespace will be expanded. */ parser_ = XML_ParserCreateNS(/*encoding = */ encoding_, /*namespaceSeparator = */ separator); else { /*...*/ }
}

Запоминаем, что сепаратор по умолчанию — ‘:’ (корректно это или нет, я не знаю). Далее файл вычитывается в буфер и парсится стандартным методом из libexpat — XML_ParseBuffer:

XMLPARSEAPI(enum XML_Status) XML_ParseBuffer(XML_Parser parser, int len, int isFinal);

При ошибке парсинга возвращается ненулевой статус, а код ошибки можно получить с помощью XML_GetErrorCode.

После получаса дебаггинга наконец нахожу, где же внутри libexpat фейлится парсинг (смотреть на GitHub):

Этот код был добавлен 12 февраля (коммит).

В качестве подопытного XML-файла используется просто <conf></conf>.

В данном случае parser->m_ns == 1 (root parser), uri == «http://www.w3.org/XML/1998/namespace» (автоматически устанавливается libexpat’ом), parser->m_namespaceSeparator == ‘:’ (установлено в LibCustomConfig). Получается любой простой файл не будет парсится, если сепаратором указать двоеточие, т.к. этот символ присутствует в URI.

Но почему же я получаю Out of memory error, если возвращается XML_ERROR_SYNTAX?? Смотрим call stack:

  • сейчас мы находимся внутри функции addBinding, которая нам возвращает XML_ERROR_SYNTAX (смотреть на GitHub)

  • вызывается она внутри функции setContext, которая внезапно возвращает bool. В данном случае XML_False (смотреть на GitHub)

  • далее startParsing, которая возвращает то же булевское значение (смотреть на GitHub)

  • а затем знакомая XML_ParseBuffer, которая по возвращенному XML_False должна понять, что же произошло (смотреть на GitHub)

И как же XML_ParseBuffer понимает, что произошло? А очень просто:

if (parser->m_parentParser == NULL && ! startParsing(parser)) { parser->m_errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR;
}

В любой непонятной ситуации возвращай XML_ERROR_NO_MEMORY. Прикольно.

Читайте так же:

  • Куда пойти учиться: методы белого увеличения трафика проекта в 2 разаКуда пойти учиться: методы белого увеличения трафика проекта в 2 раза Команда SEOnews В ближайшую неделю выясним, как собирать бесплатный трафик и добиваться кратного увеличения продаж. Рассмотрим кейсы созданию агентства и оптимизации процессов. А также научимся запускать рекламу во ВКонтакте и Яндекс.Директе и повышать ее эффективность. […]
  • Яндекс провел исследование о поведении покупателей в Черную пятницуЯндекс провел исследование о поведении покупателей в Черную пятницу Яндекс провел исследование о поведении покупателей в Черную пятницу в канун больших распродаж и дал советы продавцам по настройке рекламы перед началом акций. В 2021 году Черная пятница у многих российских продавцов продлится весь ноябрь. С каждым годом акция становится популярнее у […]
  • Нет ли сговора: что будет с ценами на жилье после проверки ФАСНет ли сговора: что будет с ценами на жилье после проверки ФАС Спросили у экспертов и застройщиков. Как предстоящая проверка ФАС может повлиять на цены на жилье Президент России Владимир Путин поручил проверить цены на жилье. По его словам. В среднем по России стоимость жилья выросла на 12%. Но есть регионы в которых подорожание достигало 30%. В […]
  • Бывшие модели OnlyFans создают свои собственные сайтыБывшие модели OnlyFans создают свои собственные сайты Когда ресурс для взрослых OnlyFans объявил о намерении отказаться от порно на площадке, а затем отменил данное решение, многие модели начали создавать свои собственные сайты. На эти шаги их подвигли опасения остаться без стабильного дохода.«Недавний запрет OnlyFans на контент для […]