CentOS 7/8 , Ubuntu でsystemd のサービスとして起動したプロセスのスタックオーバフローを抑制する方法です。
起動プロセスのスタックサイズを変更します。
正しい解決方法は、プログラムの使うスタックを減らすことですが、難しい場合の対処方法です。
設定の確認
ulimitで確認
プロセスが実行されるアカウントで ulimit -a を実行して確認します。
$ $ ulimit -a stack size (kbytes, -s) 8192
デフォルトだと最大8MBまで利用可能です。
systemd経由で起動されるプロセスの起動ユーザアカウントの ulimit -s の値を変更しても
systemd経由で起動されるプロセスには効きません。
対応方法
systemd のサービスとして起動したプロセスのリソース制限値には /etc/security/limits.conf などで設定している制限値が適用されません。
(systemdサービスにはPAM Limitが適用されません)
systemd のサービスとして起動したプロセスのリソース制限値は xxxx.serviceファイル内に設定します。
個々のサービスで設定確認
サービス名が、XXXXの場合。
# # systemctl show XXXX | grep -i stack LimitSTACK=infinity LimitSTACKSoft=8388608
起動プロセスのPIDのlimitsを直接確認する方法。
PIDが 4541の場合の例。
# # cat /proc/4541/limits Limit Soft Limit Hard Limit Units Max stack size 8388608 unlimited bytes
systemdサービスのファイルを修正
10MBに変更する手順です。
スレッドごとにスタックサイズが固定が確保されるので、その分プロセスが使うメモリが増えます。
特にマルチスレッドプログラムは、設定後にメモリの使用量も確認しましょう。
viでファイルを編集します。
# vi /lib/systemd/system/XXXX.service
…
[Service]
LimitSTACK=10485760 ←追加
サービスの設定再読み込み(リロード)
# # (1)サービス停止 # systemctl stop XXXX #(2)デーモンの設定をリロード # systemctl daemon-reload #(3)サービス起動 # systemctl start XXXX #(4)値確認 # systemctl show XXXX | grep -stack CORE LimitSTACK=10485760
スタックオーバーフローとは
■スタックってなあに?
スタック、スタックオーバーフローについて図で説明。
URL:https://uquest.tktk.co.jp/embedded/learning/lecture07-2.html
■Linuxスタックオーバーフローのハンドリング方法
少し古いですが、技術的に超詳しい内容です。
これを理解できる強者は少ないと思いますが、、、
URL:http://www.nminoru.jp/~nminoru/programming/stackoverflow_handling.html
■Windowsのプログラムでは、リンク時に設定して可能です。
Visual Studio /F (スタック サイズの設定)
URL:https://docs.microsoft.com/ja-jp/cpp/build/reference/f-set-stack-size?view=msvc-170
あとがき
最近のLinuxは、systemdに変更になり、Webで検索しても古い情報と混ざっていて、何が正解かすぐには分からないですね。