問題
先日、自分が作ったpythonプログラムで下記のようにエラーが出ていた
発生原因と対処法等わかったので、備忘もかねて投稿
Fatal Python error: Cannot recover from stack overflow.
Current thread 0x00007f434f650700 (most recent call first):
File "***.py", line 4 in ...
File "***.py", line 7 in ...
File "***.py", line 7 in ...
...
原因
ログにも記載されているようにスタックオーバーフローという問題が発生していた。
(初歩的な問題な気がぷんぷんしますが)筆者は知らなかった…。
スタックオーバーフロー (stack overflow) は、プログラム中での関数呼び出しが多すぎる時に発生する、バッファオーバーフローの一種である。
by wikipedia
(https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%95%E3%83%AD%E3%83%BC)
では、なぜ上記が発生したのか、解決策は?と思いさらに
自分の(へぼ)スクリプトを見直してみると下記のような構造になっていたことが問題であった。
def hoge()
try:
(正常処理)
except Exception as e:
(eの表示など)
hoge()
通常の正常処理中に以上処理が走ると、エラーメッセージ等を表示した上で、
再度、自分自身を呼び出していた。
自分自身を呼び出すも、スタックオーバーフローが発生しているため、
例外に入って、再度hoge
関数を呼び出し、という無限ループに...
(悲しいことにプログラムのプロセスは落ちずにエラーをはいてしまうだけになっていた)
回避策
def hoge()
try:
(正常処理)
except Exception as e:
(eの表示など)
def main():
try:
while True:
hoge()
except Exception as e:
(eの表示など)
というように例外が発生したら、いったん関数を終了させて、
メイン関数でhoge
関数で呼び出すようにする(だけでした…)
なお、上記は簡単のため、エラーが発生したときに表示しかしていないですが、
ちゃんとエラーによって適切に処理を行う必要がある場合が多いと思うので
ご注意ください
その他参考
なお、pythonでは再帰的に呼び出せる関数の数はデフォルトでは1000になっているとのことだった。
import sys
print(sys.getrecursionlimit()) # 再起呼び出しの最大値を表示 -> 1000
sys.setrecursionlimit(20000) # 再起呼び出しの最大数をセット
というように呼び出し最大回数をセットできるみたいであるが、
再起的に呼び出すつくりは危ないので、要注意(やと思ってます)