#python #segmentation-fault
#python #ошибка сегментации
Вопрос:
Могу ли я предположить, что это ошибка Python, из-за которой я получил ошибку segfault при условии, что:
- Я не использую какую-либо внешнюю библиотеку
- Я почти не использую какую-либо внутреннюю библиотеку (просто sys для увеличения предела глубины рекурсии и ввода для ввода: P
- Я не наблюдал увеличения использования оперативной памяти, которое могло бы оправдать нехватку памяти и, следовательно, ошибку segfault
- Мой код рекурсивный и не выполняет никаких дополнительных манипуляций с памятью (через ctypes или что-то еще)
Я думаю, что я не делаю ничего продвинутого в своем коде, и я, если эти условия будут выполнены, тогда, если я сделаю что-то не так, я бы ожидал, что python вызовет исключение, а не неожиданно завершит программу с кодом выхода! = 0, я прав? Как вы думаете, оправдана ли публикация проблемы в bugtracker Python в этом случае? : P
import typing
import sys
sys.setrecursionlimit(50000)
class RuleDb:
_rules: typing.Dict[int, str] = None
@classmethod
def load(cls):
if not cls._rules:
cls._rules = {}
rules = open('input', 'r').read().split('nn')[0].strip().split('n')
for rule in rules:
number, rule = rule.split(':')
number = int(number)
rule = rule.strip()
cls._rules[number] = rule
@classmethod
def get_by_id(cls, id: int):
return cls._rules[id]
@classmethod
def last_index(cls):
return max(cls._rules.keys())
def unroll(rules: RuleDb, rule_string: str):
unrolled = ''
rule_string = rule_string.replace('"','')
if len(rule_string) == 1:
if rule_string.isalpha():
return rule_string
elif rule_string.isnumeric():
return unroll(rules, rules.get_by_id(int(rule_string.strip('"'))))
if rule_string.count('|'):
unrolled = unrolled '('
left, right = rule_string.split('|')
left, right = left.strip(), right.strip()
for symbol in left.split():
unrolled = unroll(rules, symbol)
unrolled = '|'
for symbol in right.split():
unrolled = unroll(rules, symbol)
unrolled = ')'
elif not rule_string.count('|'):
for symbol in rule_string.split():
unrolled = unroll(rules, symbol)
return unrolled
rules_db = RuleDb()
rules_db.load()
print(
unroll(rules_db, rules_db.get_by_id(0))
)
Комментарии:
1. При переполнении стека мы не можем принимать ссылки на код. Поместите соответствующий код, чтобы продемонстрировать проблему, в сам вопрос.
2. Хорошо, отредактировано, если это так.
3. Короткий ответ: вероятно, нет. Длинный ответ: я бы сомневался, что python имеет не менее 8 миллионов пользователей ( slashdata-website-cms.s3.amazonaws.com/sample_reports /… ) имеет в нем какой-то изъян, который заметили только вы. Обычно именно в вашем коде есть ошибка.
4. Нет, это ваша вина , потому что вы это сделали
sys.setrecursionlimit(50000)
. Есть причина , по которой существует ограничение на стек: чтобы избежать ошибок segfaults и переполнения стека.
Ответ №1:
sys.setrecursionlimit(50000)
Скорее всего, это ваша ошибка, а не интерпретатора Python.
Из документов Python https://docs.python.org/3/library/sys.html#sys.setrecursionlimit:
Максимально возможный предел зависит от платформы. Пользователю может потребоваться установить предел выше, если у них есть программа, требующая глубокой рекурсии, и платформа, поддерживающая более высокий предел. Это следует делать с осторожностью, потому что слишком высокий предел может привести к сбою.
Комментарии:
1. Я не вижу никакой ссылки на ограничение рекурсии в вопросе.
2. Вопрос был отредактирован. pastebin.com/kE0aaYWb
3. Да, извините, я вижу, что существуют некоторые специальные правила при размещении ссылки на pastebin, поэтому у меня возникли некоторые проблемы с этим. @pavi2410 спасибо 🙂