TIL: how to debug randomly hanging Python applications

Usually, if a Python-based application hangs, you either read logs or grab one of the PBD-based solutions, attaching to the application, and uses the Python console for investigation. The approach is straightforward; for example, you installed pdb-attach, and add a few lines to your application:

import pdb_attach
pdb_attach.listen(50000)

and expect that “magic” will just works:

> python -m pdb_attach <PID> 50000
(Pdb) YOU HAVE PDB SESSION HERE

But sometimes, magic is broken, and my theory is (I didn’t search for proof) that this is due to GIL. So, sometimes, no PDB prompt after you have attached to the application with PDB. In my case, the application hang in the multiprocessing.Process call where I used a gRPC server. The gRPC server didn’t react to the termination request, the process cannot stop, and like aggravating circumstances, all these are a part of PyTest that hang 1 of 20 executions.

This is a general PDB-based debuggers issue, which means all other tools like pyrasite-shell and PyTest PBD integration also don’t work. The only option here is GDB for Python, which is surprisingly amazing! First of all, you need to install Python extension for GDB.

sudo apt-get install python3.9-dbg

Then you can connect to your Python application which is a regular Python process with GDB, and explore the call-stack!

> gdb

(GDB) attach <PID>
(GDB) py-bt

If you use not APT-based Linux, search for proper instruction here.

Возвращение к C++

Последние лет 6 я всё меньше и меньше занимался разработкой на C++, количество использования фактически шло по убывающей до нулевого значения год назад. Чего только не было в качестве основного языка, и Go, и Elixir и даже небольшие отрезки времени чистый Python. Но так случилось, что с переходом на новое место работы C++ вновь стал моим основным рабочим инструментом. Появилась насущная необходимость шустро освежить знания в голове и, в идеале, совместить это с чем-то полезные. В итоге я решил решил порешать задачки на тему криптографии от cryptopals дабы как-то скрасить ожидание открытия заинтересовавшего меня курса по криптографии на Коурсере.  Ну а так как теперь мне действительно есть с чем сравнивать C++, ощущения от языка получаются более цельные, как мне кажется. Continue reading

Windows, Linux и шифрованные диски

Я очень долго использовал устройства Apple в качестве основных рабочих систем и дома и на работе, лет 10, наверное. В целом, это удобно, так как доступны как все приложения которые нужны как для хобби (Capture One & Photoshop), так и рабочие инструменты. Ко времени очередного обновления железа я успел не только заинтересоваться машинным обучением и внимательно посмотреть на современный рынок железа, но и упереться в то, что Apple и GPGPU не совместимы в принципе. После всех метаний и попыток запустить то что мне хочется на устройствах от Apple у меня состоялся большой исход к их конкурентам, ведь зачем платить больше и не иметь доступа к GPGPU, если можно его получить за меньшие деньги?

Перебравшись на Windows дома я довольно долго пытался убедить себя в том, что к всему этому ужасу можно привыкнуть и я просто забыл как классно работать в Windows разработчику… но все же нет. Привыкнуть к PowerShell и его окружению вместо Bash и стандартного набора команд POSIX, а так же отсутствию не глючного терминала просто не возможно. И WSL тут никак не спасает, так как подсистема не только ощутимо тормозит на любом I/O, но и довольно глючная, а кривые терминалы еще сильнее сужают возможности её использования в разработке.

Continue reading

C++ идет в облака

Попасть на CppCon в этом году по ряду причин не вышло, поэтому я смотрю видео на YouTube. В процессе просмотра списка докладов глаз моментально зацепился за The Design of the C++ Runtime for AWS Lambda и я не разочаровался. Доклад в чем-то знаковый, так как он показывает применимость языка в области о которой C++ разработчики не думают и, обычно, ничего не знают.

Ключевые моменты из доклада:

  • AWS SDK for C++ позволяет оперировать всеми сервисами AWS, SDK доступен на GitHub. Там же можно найти огромное количество примеров использования.
  • SDK использует libCURL и разработчик должен сам разобраться с инициализацией хранилища сертификатов, расположение которого, конечно же, может зависеть от версии Linux.
  • Много воевали с libC, который довольно объемный с точки зрения набора библиотек и дистрибутиво-зависимый. Остановились на решении паковать все файлы проекта (включая libC) в один архив и запускать через ld-linux.so.
  • Если хочется уменьшить количество файлов привносимых libC, хотя целесообразность этого действия под вопросом так как еще есть libC++/libStdC++, то можно воспользоваться musl.
  • AWS гарантирует минимальный уровень процессора SkyLake, так что если вам нужен SIMD, то вполне можно включать процессоро-специфические оптимизации.

При том, что один из основных сценариев использования лямбды это – по-быстрому что-то посчитать, причем “по-быстрому” тут ключевое ведь оплата за время, то потенциал использования C++ (еще и с включенными SIMD-оптимизациями) на этом поприще выглядит очень заманчивым.

Rust и не звездные команды

Сегодня мне удалось немного с другой стороны посмотреть на Rust, что дало интересную пищу для размышлений. В общем случае я склонялся к мнению, что Rust – это, конечно, прекрасно, но по уровню сложности он мало чем уступает C++, а при таком раскладе зачем нужно разбираться с еще одним монстром? Но, похоже что, эта позиция может быть довольно большим заблуждением.

Continue reading

Clojure и AWS Lambda

Последнее время я неспешно работаю над своим новостным C++ ботом и в качестве заключительного шага его нужно где-то “поселить” жить. Вариантов, конечно же довольно много, начиная своим компьютером заканчивая облаками, но наиболее экономически целесообразным и простым в поддержке выглядит какое-либо бессерверное решение, например AWS Lambda. Так как Clojure приложение как Lambda я еще никогда не запускал, то решил вынести эксперименты отдельно от основного проекта. Оказалось не сложнее чем с Go, всего-то нужно взять подходящую библиотеку для простой и наглядной реализации точки входа, сделать правильную сборку, да не забыть про Terraform для удобного управления инфраструктурой.
Continue reading

Haskell – это прекрасно, но…

Правда, я не понимаю как я мог заниматься разработкой в течении 18 лет и не удосужиться прочитать хотя бы одной книги по Haskell и даже не написать простенького “Hello world!” на этом изумительном языке. Наверное, меня всё время так или иначе отпугивали разные слухи и истории на тему того, какой это дико сложный и непойми-нахрена-нужный язык. Не иначе!

К счастью у меня, с одной стороны, нашлось довольно большое количество свободного времени для изучения чего-то совершенно не нужного в повседневной работе, а с другой стороны, мне посоветовали несколько книг по Haskell в рамках внезапно разросшейся дискуссии об этом языке на Facebook и пусть ни одна из них мне не подошла, но начало было положено. Проблема с книгами собственно в том, что имея за плечами изрядный опыт программирования, большинство из них выглядят невероятно скучными. Ну зачем долго и в мельчайших деталях обсуждать что такое let или сопоставление с образцом? Ясно же, что Haskell не будет для кого-то первым языком и у читателя уже есть что-то за плечами для того, что бы провести аналогии и понять о чем идет речь с полуслова. К моей радости я наткнулся на What I wish I Knew, которая отвечает на изрядное количество прикладных вопросов относительно языка и наиболее распространенных паттернов использования и мне где-то я разыскал рекомендацию Get Programming with Haskell в которой кратко и по делу рассматривают основные концепции языка. Сначала мне эта книга сильно не понравилась, но оказалось что нужно просто пропустить/пролистать первые две главы и всё будет просто великолепно. Continue reading

Основная головная боль в мире C++

В процессе обсуждения увлекательного вопроса “за что не любят современный C++” всплыл интересный список последствий UB оптимизаций. В отличие от довольно простого управления памятью которое мы получили начиная с C++14, UB – это действительно ужас-ужас, который фактически не реально держать в голове.

Великолепный пример с переполнением при умножении i на миллиард, который позволяет компилятору сильно “упростить” цикл:
Continue reading

Два года с Go

Сейчас подвожу итоги где-то 2-х лет разработки серии проектов на Go и довольно приятно удивляюсь тому, насколько хорошую защиту от дурака имеет Go по-умолчанию. Выстрелить себе в ногу просто невероятно сложно и в общем случае разработчик может просто сконцентрироваться на задаче не думая про UB, особенности move semantic и кучу других вещей, которые постоянно должны быть в голове у C++ разработчика.

Если отбросить очень сильное упрощение языка и попытаться выделить какие же именно решения позволили сильно упростить работу, то я бы отметил два: 1) отсутствие классов и наследования, 2) запрет на циклические импорты.

Continue reading

С++ и надежный, безопасный код

Довольно часто можно встретить высказывания о том, что C++ и надежный, безопасный и легко поддерживаемых код несовместимы. Особенно часто такими высказываниями грешат адепты управляемых языков и довольно долгое время это было в общем-то небезосновательно. Сам я остро почувствовал данную проблему с C++ после того как основательно погрузился в Go, где благодаря большому количеству утилит для автоматического анализа кода, удается добиться приличного уровня кодовой базы проекта с относительно не высокими временными затратами. К счастью, в мире C++ в последние годы ситуация сильно изменилась и получить сопоставимый по качеству уровень стало возможно с приблизительно сопоставимыми усилиями.

Единый стиль форматирования

Казалось бы, единый стиль форматирования проекта – это мелочь, но ведь не просто так почти каждая уважающая себя компания имеет увесистый документ “BestCompanyInTheWorld Coding Standard”, который как минимум на половину состоит из того, как код должен быть отформатирован. При этом, код в BestCompanyInTheWorld почти наверняка отформатирован вразнобой, так как применение стандарта контролируется в лучшем случае в процессе ревью, но кто же помнит все эти хитросплетения пробелов и скобок? Работая с Go я впервые оценил прелесть того, что весь код включая сторонние библиотеки действительно написан в едином стиле, так как существует единое правило форматирования для всего языка. Эта казалось бы мелочь очень сильно упрощает работу над чужой кодовой базой и в случае с Go легко достигается автоматически при помощи доступных по умолчанию форматтеров.
Continue reading