Я реализую алгоритм поиска графа Strong Connected Component (SCC) Kosaraju в Python.
Программа отлично работает с небольшим набором данных, но когда я запускаю ее на сверхбольшом графе (более 800 000 узлов), появляется сообщение «Ошибка сегментации».
Что может быть причиной этого? Спасибо!
Дополнительная информация: сначала я получил эту ошибку при работе с сверхбольшим набором данных:
"RuntimeError: maximum recursion depth exceeded in cmp"
Затем я сбрасываю предел рекурсии, используя
sys.setrecursionlimit(50000)
но получил "Ошибка сегментации"
Поверьте, это не бесконечный цикл, он работает правильно на относительно небольших данных. Возможно программа исчерпала свои ресурсы?
Ответы:
Это происходит, когда расширение Python (написанное на C) пытается получить доступ к недоступной памяти.
Вы можете отследить это следующими способами.
sys.settrace
в самую первую строку кода.Используйте,
gdb
как описано Марком в этом ответе .. В командной строкеgdb python (gdb) run /path/to/script.py ## wait for segfault ## (gdb) backtrace ## stack trace of the c code
источник
Я понимаю, что вы решили свою проблему, но для других, читающих эту ветку, вот ответ: вам нужно увеличить стек, который ваша операционная система выделяет для процесса python.
Способ сделать это зависит от операционной системы. В Linux вы можете проверить с помощью команды
ulimit -s
свое текущее значение и увеличить его с помощьюulimit -s <new_value>
Попробуйте удвоить предыдущее значение и продолжайте удваивать, если оно не работает, пока не найдете то, которое работает или не исчерпает память.
источник
lsof
и использоватьgrep
илиwc -l
отслеживать все.Ошибка сегментации является общей, для этого есть много возможных причин:
источник
Обновление ulimit сработало для моей реализации SCC Kosaraju, исправив segfault как в реализациях Python (Python segfault… кто знал!), Так и в реализациях C ++.
Для своего MAC я узнал возможный максимум через:
$ ulimit -s -H 65532
источник
Поиск Google нашел мне эту статью, и я не видел, чтобы обсуждалось следующее "личное решение".
Мое недавнее раздражение по поводу Python 3.7 в подсистеме Windows для Linux заключается в том, что на двух машинах с одной и той же библиотекой Pandas одна выдает мне,
segmentation fault
а другая сообщает предупреждение. Было непонятно, какая из них новее, но «переустановка»pandas
решает проблему.Команда, которую я запускал на глючной машине.
Дополнительные сведения: я запускал идентичные сценарии (синхронизированные через Git), и оба являются машиной Windows 10 с WSL + Anaconda. Вот скриншоты, чтобы понять причину. Кроме того, на машине, на которую
python
будетSegmentation fault (core dumped)
выдавать жалоба командная строка , Jupyter lab просто перезагружает ядро каждый раз. Что еще хуже, никакого предупреждения не последовало.Обновления через несколько месяцев: я перестал размещать серверы Jupyter на компьютере с Windows. Теперь я использую WSL в Windows для получения удаленных портов, открытых на сервере Linux, и запуска всех моих заданий на удаленном компьютере Linux. Я ни разу не сталкивался с ошибками выполнения в течение многих месяцев :)
источник
У меня возникла эта ошибка сегментации после обновления dlib на RPI. Я отследил стек, как это было предложено Шиплу Мокаддим выше, и остановился на библиотеке OpenBLAS.
Поскольку OpenBLAS также является многопоточным, его использование в многопоточном приложении приведет к экспоненциальному увеличению числа потоков до тех пор, пока не возникнет ошибка сегментации. Для многопоточных приложений установите OpenBlas в однопоточный режим.
В виртуальной среде Python скажите OpenBLAS использовать только один поток, отредактировав:
$ workon <myenv> $ nano .virtualenv/<myenv>/bin/postactivate
и добавить:
export OPENBLAS_NUM_THREADS=1 export OPENBLAS_MAIN_FREE=1
После перезагрузки я смог запустить все свои приложения для распознавания изображений на rpi3b, которые ранее его вылетали.
ссылка: https://github.com/ageitgey/face_recognition/issues/294
источник
Похоже, у вас закончилась стековая память. Вы можете захотеть увеличить его, как сказал Давид. Чтобы сделать это в коде Python, вам нужно будет запустить ваш main () с помощью потоковой передачи:
def main(): pass # write your code here sys.setrecursionlimit(2097152) # adjust numbers threading.stack_size(134217728) # for your needs main_thread = threading.Thread(target=main) main_thread.start() main_thread.join()
Источник: сообщение c1729 на codeforces . Запускать его с PyPy немного сложнее .
источник