Comments 12
Запоминаем, что сепаратор по умолчанию — ':' (корректно это или нет, я не знаю).
Совершенно некорректно, документация по libexpat прямо говорит не использовать символ который может встречаться в XML:
Constructs a new parser that has namespace processing in effect. Namespace expanded element names and attribute names are returned as a concatenation of the namespace URI, sep, and the local part of the name. This means that you should pick a character for sep that can't be part of an URI. Since Expat does not check namespace URIs for conformance, the only safe choice for a namespace separator is a character that is illegal in XML. For instance, '\xFF' is not legal in UTF-8, and '\xFFFF' is not legal in UTF-16.
Ну, для меня сообщение от программы out of memory обычно означает, что это программа неправа, а память есть. Потому что когда памяти нет, то программа обычно ничего не сообщает, а OOM зачитывает некролог с выражением. Чаще всего той программе, которая "виновата", но иногда и кому-то непричастному.
Зависит от языка. Да, если это Си то нужно аккуратно всё проверять. А если что то чуть выше уровнем вроде Го где аллоцирует рантайм, то там по крайней мере сообщит перед паникой.
Но, конечно, пенять на ОС это последнее дело ?
За вычетом java (где свои лимиты памяти), обычные нативные бинарники под линукс ENOMEM на нормальной конфигурации никогда не получают, т.к. есть оверкоммит по памяти. Когда память заканчивается for real, на машине уже обычно есть выделенной памяти в 2-3 раза больше, чем есть физической, так что память заканчивается не в момент её запроса, а в момент попытки использовать. И тогда ядро решает, кого убить, чтобы освободить память. Называется oom (out of memory), плюс особо всеми любимый oom killer.
Так что для go, C, C++, Rust, python и т.д. получить ENOMEM практически не возможно (если только не запросить нереально большое количество памяти с самого начала).
Кроме нехватки памяти есть еще cgroups в которых память бывает зажимают.
так что память заканчивается не в момент её запроса, а в момент попытки использовать.
Да, malloc() в линуксе почти никогда не фейлится, но это зависит от настроек оверкоммита в sysctl. Тем не менее...
Так что для go, C, C++, Rust, python и т.д. получить ENOMEM практически не возможно (если только не запросить нереально большое количество памяти с самого начала).
...конкретно в Go я бывало встречал панику по memory allocation failure ещё до того как в ядре сработал OOM.
Судя по исходнику рантайма это именно ENOMEM:
Пересаживаюсь на свежую LTS версию Ubuntu
как я переустанавливал ОС из-за libexpat
WAT. В чём была проблема даунгрейднуть libexpat или собрать другую версию в песочнице? Зачем переставлять всю систему?
Я ведь не знал заранее, что проблема в обновлении libexpat. К тому же, как и написано в статье, вся система в целом стала очень нестабильной после обновления. Добавьте к этому очень странный код ошибки, и в этоге получаем вывод, что надо сносить систему
Признаю, что сделал это скорее из нежелания нормально разбираться, что не так))
Кстати, заметил тут вот ещё одну ошибку:
В данном случае parser->m_ns == 1 (root parser), uri == "http://www.w3.org/XML/1998/namespace" (автоматически устанавливается libexpat'ом)
Это пространство имён — вовсе не пространство имён по умолчанию, а пространство имён связанное с префиксом xml. По умолчанию же пространство имён — пустая строка, и именно пустая строка должна была оказаться в массиве uri.
Маленькая история о том, как я переустанавливал ОС из-за libexpat, или как не стоит обрабатывать ошибки