COBOL/エンタープライズ製品 技術情報(FAQ)


Linux/UNIX環境でのランタイムエラー 114 発生時の調査方法


ランタイムエラー 114 の発生原因

COBOL アプリケーションプロセスで OS のメモリアクセス違反が発生すると、以下のようなランタイムエラーメッセージが表示されます。メッセージ末尾の (シグナル nn) はメモリアクセス違反の発生時に OS から受信したシグナルで、この例での (シグナル 11) はセグメンテーションフォールト(SIGSEGV)を意味します。

実行 エラー: ファイル '/home/user01/app/MF01001.gnt
エラーコード: 114, pc=0, call=1, seg=0
114  メモリ領域外の項目にアクセスしようとしている (シグナル 11)

このエラーが発生する原因は非常に多岐に及びますが、一般には以下のような原因が考えられます。ユーザーデバッグを行い、発生箇所を特定し、問題を解決する必要があります。

・アプリケーションの非COBOL部分のエラー
・CALL文内のパラメータの不整合
・スタックオーバーフロー
・不正な部分参照
・無効なポインタ値
・有効範囲外の添字
・不正なリンクオプションやプロシージャ



gdb とコアダンプを使用したデバッグ方法

gdb とコアダンプを使用したデバッグ方法を紹介します。以下は Linux 上で Gnu デバッガの gdb を使用する例です。UNIX 上の dbx でも同様にコアダンプを使用したデバッグを行うことができます。

  1. 114 エラーが発生するサンプルプログラムを準備します。ここでは SUB2.cbl の linkage section のデータ項目のサイズに誤りがあるために 114 エラーが発生するサンプルプログラムを使用します。
    $ cat MAIN.cbl
           working-storage section.
           01 wk-test01 pic x(3).
           procedure division.
               call 'SUB1' using wk-test01.
               call 'SUB2' using wk-test01.
               call 'SUB3' using wk-test01.
               stop run.
    
    $ cat SUB1.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(5).
           procedure division using lk-test01.
               move 'ABC' to lk-test01.
               goback.
    
    $ cat SUB2.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(10000).
           procedure division using lk-test01.
               move spaces to lk-test01.
               goback.
    
    $ cat SUB3.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(3).
           procedure division using lk-test01.
               move 'ABC' to lk-test01.
               goback.
    
  2. サンプルプログラムをコンパイルします。
    $ cob -x MAIN.cbl SUB1.cbl SUB2.cbl SUB3.cbl
    MAIN.cbl:
    SUB1.cbl:
    SUB2.cbl:
    SUB3.cbl:
    $
    
  3. サンプルプログラムを実行し、114 エラーが発生することを確認します。
    $ ./MAIN
    実行 エラー: ファイル 'MAIN'
    エラーコード: 114, pc=0, call=1, seg=0
    114  メモリ領域外の項目にアクセスしようとしている (シグナル 11)
    $
    
  4. ランタイム構成ファイルを準備します。実行時チューナー:signal_regime を使用し、シグナル 11 が発生した場合は、COBOL ランタイムシステムがキャッチしない設定にしています。114 エラーの多くは、シグナル 11 ですがシグナル 10 の場合もあります。その場合は、signal_regime(11) を signal_regime(10) に読み替えてください。
    $ cat myconfig.cfg
    set signal_regime(11)=2
    $
    
  5. 環境変数:COBCONFIG にランタイム構成ファイルを設定します。
    $ export COBCONFIG=/home/tarot/ko/00000/myconfig.cfg
    
  6. サンプルプログラムを実行します。
    $ ./MAIN
    Segmentation fault (コアダンプ)
    $
    
  7. コアダンプが生成されていることを確認します。
    $ ls -l core*
    -rw------- 1 tarot tarot 614400  7月  9 12:01 core.22621
    $
    
  8. gdb を使用し、デバッグを行います。ここでの出力メッセージの内容から、セグメンテーションフォールト (シグナル 11) が SUB2 内で発生したことがわかります。
    $  gdb ./MAIN core.22621
    Traceback (most recent call last):
      File "/usr/share/gdb/python/gdb/__init__.py", line 105, in auto_load_packages
        __import__(modname)
      File "/usr/share/gdb/python/gdb/function/caller_is.py", line 57, in <module>
        CallerIs()
      File "/usr/share/gdb/python/gdb/function/caller_is.py", line 30, in __init__
        super (CallerIs, self).__init__ ("caller_is")
    LookupError: unknown encoding: WINDOWS-31J
    <・・・一部省略・・・>
    GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7
    Copyright (C) 2013 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-redhat-linux-gnu".
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>...
    Reading symbols from /home/tarot/ko/00000/MAIN...(no debugging symbols found)...done.
    [New LWP 22621]
    Core was generated by `./MAIN'.
    Program terminated with signal 11, Segmentation fault.
    #0  0x0000000000401204 in SUB2 ()
    Missing separate debuginfos, use: debuginfo-install glibc-2.17-222.el7.x86_64
    (gdb)
    
  9. エラー発生箇所の確認のため where コマンドを実行します。最初の出力行が問題発生箇所を示しており、前述の通り SUB2 が問題発生箇所であることの他、その SUB2 がどのような経路で呼び出されたものかが後続行の内容からわかります。
    (gdb) where
    #0  0x0000000000401204 in SUB2 ()
    #1  0x0000000000400f00 in MAIN ()
    #2  0x00007f40b8cce18c in mFt_xe_xcall ()
       from /opt/mf/ED40//lib/libcobrts64.so.3
    #3  0x00007f40b8c99dcd in cobol_main () from /opt/mf/ED40//lib/libcobrts64.so.3
    #4  0x00007f40b8c99e2b in _mFgmain () from /opt/mf/ED40//lib/libcobrts64.so.3
    #5  0x0000000000400d84 in main ()
    (gdb)
    


anim とコアダンプを使用したデバッグ方法

anim とコアダンプを使用したデバッグ方法を紹介します。anim は弊社製品のデバッグ用ツールです。anim コマンドは開発環境製品である Visual COBOL/Enterprise Developer のコンポーネントであり、実行環境製品である COBOL Server/Enterprise Server には含まれていません。本番運用で生成したコアファイルを解析するには、コアファイルを開発環境に転送して参照する必要があります。デバッグに際しては以下のリソースが必要となります。

  1. コアファイル
    animを起動する際にカレントディレクトリに配置します。
  2. .idyファイル
    animを起動する際にカレントディレクトリに配置します。
  3. ソースファイル
    .gnt/.idy を生成した際に置かれていたディレクトリにあるファイルが参照されます。
    コンパイル後にソースが修正されていると正しく行位置が表示されません。~


  1. 114 エラーが発生するサンプルプログラムを準備します。ここでは SUB2.cbl の linkage section のデータ項目のサイズに誤りがあるために 114 エラーが発生するサンプルプログラムを使用します。
    $ cat MAIN.cbl
           working-storage section.
           01 wk-test01 pic x(3).
           procedure division.
               call 'SUB1' using wk-test01.
               call 'SUB2' using wk-test01.
               call 'SUB3' using wk-test01.
               stop run.
    
    $ cat SUB1.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(5).
           procedure division using lk-test01.
               move 'ABC' to lk-test01.
               goback.
    
    $ cat SUB2.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(10000).
           procedure division using lk-test01.
               move spaces to lk-test01.
               goback.
    
    $ cat SUB3.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(3).
           procedure division using lk-test01.
               move 'ABC' to lk-test01.
               goback.
    
  2. サンプルプログラムをコンパイルします。
    $ cob -xg MAIN.cbl SUB1.cbl SUB2.cbl SUB3.cbl
    MAIN.cbl:
    SUB1.cbl:
    SUB2.cbl:
    SUB3.cbl:
    $
    
  3. サンプルプログラムを実行し、114 エラーが発生することを確認します。
    $ ./MAIN
    実行 エラー: ファイル 'MAIN'
    エラーコード: 114, pc=0, call=1, seg=0
    114  メモリ領域外の項目にアクセスしようとしている (シグナル 11)
    $
    
  4. ランタイム構成ファイルを準備します。実行時チューナー:signal_regime を使用し、シグナル 11 が発生した場合は、COBOL ランタイムシステムがキャッチしない設定にしています。
    $ cat myconfig.cfg
    set signal_regime(11)=2
    $
    
  5. 環境変数:COBCONFIG にランタイム構成ファイルを設定します。
    $ export COBCONFIG=/home/tarot/ko/00000/myconfig.cfg
    
  6. サンプルプログラムを実行します。
    $ ./MAIN
    Segmentation fault (コアダンプ)
    $
    
  7. コアダンプが生成されていることを確認します。
    $ ls -l core*
    -rw------- 1 tarot tarot 614400  7月  9 12:04 core.22749
    $
    
  8. amin コマンドを使用し、デバッグを行います。SUB2 の move spaces to lk-test01. で 114 エラーが発生していることがわかります。
    $ anim core.22749
    
         1 working-storage section.
         2 linkage section.
         3 01 lk-test01 pic x(10000).
         4 procedure division using lk-test01.
         5     move spaces to lk-test01.       ← 初期表示でフォーカス
         6     goback.
    
    
    AnimateqSUB2.gnt/.o/.exeqqqqqqqqqqqqqqqqqqqqLevel=**qSpeed=5qInsqCapsqNumqScroll
    F1=help F2=view F3=align F4=exchange F5=where F6=look-up  F9/F10=word-</> Escape
    Step Go Zoom Perform Reset Break Env Query Find Locate Text Do View-threads More
    114  メモリ領域外の項目にアクセスしようとしている -
    $
    

stackdump_on_error による調査方法

Visual COBOL / Enterprise Developer 5.0 では、実行時チューナー:stackdump_on_error が追加され、ダンプログファイルを生成し、そのログを確認することでエラー発生個所を特定することができます。この実行時チューナーは、OS 側のコアダンプの生成の設定には依存しません。また、実行モジュールとランタイム構成ファイルのみがあればダンプログファイルを生成させることができます。

  1. 114 エラーが発生するサンプルプログラムを準備します。ここでは SUB2.cbl の linkage section のデータ項目のサイズに誤りがあるために 114 エラーが発生するサンプルプログラムを使用します。
    $ cat MAIN.cbl
           working-storage section.
           01 wk-test01 pic x(3).
           procedure division.
               call 'SUB1' using wk-test01.
               call 'SUB2' using wk-test01.
               call 'SUB3' using wk-test01.
               stop run.
    
    $ cat SUB1.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(5).
           procedure division using lk-test01.
               move 'ABC' to lk-test01.
               goback.
    
    $ cat SUB2.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(10000).
           procedure division using lk-test01.
               move spaces to lk-test01.
               goback.
    
    $ cat SUB3.cbl
           working-storage section.
           linkage section.
           01 lk-test01 pic x(3).
           procedure division using lk-test01.
               move 'ABC' to lk-test01.
               goback.
    
  2. サンプルプログラムをコンパイルします。
    $ cob -x MAIN.cbl SUB1.cbl SUB2.cbl SUB3.cbl
    MAIN.cbl:
    SUB1.cbl:
    SUB2.cbl:
    SUB3.cbl:
    $
    
  3. サンプルプログラムを実行し、114 エラーが発生することを確認します。
    $ ./MAIN
    実行 エラー: ファイル 'MAIN'
    エラーコード: 114, pc=0, call=1, seg=0
    114  メモリ領域外の項目にアクセスしようとしている (シグナル 11)
    $
    
  4. ランタイム構成ファイルを準備します。実行時チューナー:set stackdump_on_error を使用し、ダンプログファイルが生成される設定にしています。
    $ cat myconfig.cfg
    set stackdump_on_error=1
    $
    
  5. 環境変数:COBCONFIG にランタイム構成ファイルを設定します。
    $ export COBCONFIG=/home/tarot/ko/00000/myconfig.cfg
    
  6. サンプルプログラムを実行します。
    $ ./MAIN
    実行 エラー: ファイル 'MAIN'
    エラーコード: 114, pc=0, call=1, seg=0
    114  メモリ領域外の項目にアクセスしようとしている (シグナル 11)
    $
    
  7. ダンプログファイルが生成されていることを確認します。
    $ ls -l *.log
    -rw-rw-r-- 1 tarot tarot 1137  7月 10 11:12 MAIN.stackdump.22936.log
    $
    
  8. cat コマンドでダンプログファイルの内容を確認します。MAIN.cbl の 5 行目部分で呼ばれた SUB2.cbl の 5 行目で 114 エラーが発生していることがわかります。
    $ cat MAIN.stackdump.22936.log
    Micro Focus Process Diagnostics.
    Displaying the stacks and threads for process 0x5998
    
    Error information:
    
    実行 エラー: ファイル 'MAIN'
    エラーコード: 114, pc=0, call=1, seg=0
    114  メモリ領域外の項目にアクセスしようとしている (シグナル 11)
    
    -----Thread Id: 0x1 Current thread, contains COBOL.
    /usr/lib64/libc-2.17.so+0xC517B
    /opt/mf/ED50/lib/libcobrts64.so.3+0x4AAE1
    /opt/mf/ED50/lib/libcobrts64.so.3+0x84926
    /opt/mf/ED50/lib/libcobrts64.so.3+0x84CC5
    /opt/mf/ED50/lib/libcobrts64.so.3+0x4378C
    /opt/mf/ED50/lib/libcobrts64.so.3+0x423A2
    /opt/mf/ED50/lib/libcobrts64.so.3+0x49C16
    /opt/mf/ED50/lib/libcobrts64.so.3+0x48E43
    /opt/mf/ED50/lib/libcobrts64.so.3+0x459B8
    /opt/mf/ED50/lib/libcobrts64.so.3+0x48E8D
    /opt/mf/ED50/lib/libcobrts64.so.3+0x4970D
    /opt/mf/ED50/lib/libcobrts64.so.3+0x49843
    /usr/lib64/libc-2.17.so+0x362EF
    /home/tarot/ko/00000/MAIN+0x12FA SUB2.cbl Line:5
    /home/tarot/ko/00000/MAIN+0xFF9 MAIN.cbl Line:5
    /opt/mf/ED50/lib/libcobrts64.so.3+0xBC60A
    /opt/mf/ED50/lib/libcobrts64.so.3+0x8B428
    /opt/mf/ED50/lib/libcobrts64.so.3+0x8B476
    /home/tarot/ko/00000/MAIN+0xE7F
    /usr/lib64/libc-2.17.so+0x22443
    /home/tarot/ko/00000/MAIN+0xD94
    $
    


コアダンプ生成における注意事項

OS 環境によってはコアダンプが出力されないよう設定されている場合があります。OS 側の設定でコアダンプを出力できる設定になっているかどうかをご確認ください。以下の例のように「ulimit -c」コマンドの実行結果が 0 の場合はコアダンプは出力されません。

# ulimit -c
0

この場合、システム管理者様にご相談のうえ、コアダンプを出力できるよう設定を変更してください。以下はコアダンプの出力サイズを無制限にするコマンド例です。

# ulimit -S -c unlimited



製品マニュアルの参照箇所 - Server Express


Server Express 5.1J のマニュアルトップページは以下です。

・Server Express 5.1J マニュアルトップ
https://www.microfocus.co.jp/manuals/SE51/sx51indx.htm

一般保護例外の詳細は、マニュアルトップから [プログラム開発] > [第 5 章 保護違反エラーへの対処] に進み、その配下の各トピックをご参照ください。

・保護違反エラーへの対処
https://www.microfocus.co.jp/manuals/SE51/prxept.htm
マニュアルトップからは、[プログラム開発] > [第 5 章 保護違反エラーへの対処] に進んでください。

実行時チューナーの詳細は、マニュアルトップから [実行時構成] に進み、その配下の各トピックをご参照ください。[実行時チューナーのリスト] に signal_regime 等の各種実行時チューナーの説明があります。

anim コマンドやその機能に関しての詳細は、マニュアルトップから [デバッギングハンドブック] に進み、その配下の各トピックをご参照ください。


製品マニュアルの参照箇所 - Visual COBOL


Visual COBOL 4.0 のマニュアルトップページは以下です。

・Visual COBOL 4.0 - マニュアルトップ
https://www.microfocus.co.jp/manuals/VC40/vc40indx.html

一般保護例外の詳細は下記のトピック配下をご参照下さい。

・記憶保護例外
https://www.microfocus.co.jp/manuals/VC40/Eclipse/GUID-27FBD013-7DF2-4FF7-9F4A-CA6E287FCF4C.html
マニュアルトップからは、[プログラミング] > [問題解決と診断ツール] > [記憶保護例外] に進んでください。

実行時チューナーの詳細は下記のトピック配下をご参照下さい。[実行時チューナーのリスト] に signal_regime 等の各種実行時チューナーの説明があります。

・実行時チューナー
https://www.microfocus.co.jp/manuals/VC40/Eclipse/GUID-FE176B48-9455-470A-855A-C0A62734DE51.html
マニュアルトップからは、[リファレンス] > [ランタイム システムの構成] > [実行時チューナー] に進んでください。

anim コマンドやその機能に関しての詳細は下記のトピック配下をご参照下さい。

・Character Animator によるデバッグ (UNIX)
https://www.microfocus.co.jp/manuals/VC40/Eclipse/GUID-B2B1D3B7-AEC7-4B30-83B6-8C44E87AFAF1.html
マニュアルトップからは、[IDE によるアプリケーションの開発] > [COBOL アプリケーションのデバッグ] > [デバッグ シナリオ] > [Character Animator によるデバッグ (UNIX)] に進んでください。



製品マニュアルの参照箇所 - Enterprise Developer


Enterprise Developer 4.0 のマニュアルトップページは以下です。

・Enterprise Developer 4.0 - マニュアルトップ
https://www.microfocus.co.jp/manuals/ED40/ed40indx.html

一般保護例外の詳細は下記のトピック配下をご参照下さい。

・記憶保護例外
https://www.microfocus.co.jp/manuals/ED40/Eclipse/GUID-27FBD013-7DF2-4FF7-9F4A-CA6E287FCF4C.html
マニュアルトップからは、[プログラミング] > [問題解決と診断ツール] > [記憶保護例外] に進んでください。

実行時チューナーの詳細は下記のトピック配下をご参照下さい。[実行時チューナーのリスト] に signal_regime 等の各種実行時チューナーの説明があります。

・実行時チューナー
https://www.microfocus.co.jp/manuals/ED40/Eclipse/GUID-FE176B48-9455-470A-855A-C0A62734DE51.html
マニュアルトップからは、[リファレンス] > [ランタイム システムの構成] > [実行時チューナー] に進んでください。

anim コマンドやその機能に関しての詳細は下記のトピック配下をご参照下さい。

・Character Animator によるデバッグ (UNIX)
https://www.microfocus.co.jp/manuals/ED40/Eclipse/GUID-B2B1D3B7-AEC7-4B30-83B6-8C44E87AFAF1.html
マニュアルトップからは、[IDE によるアプリケーションの開発] > [COBOL アプリケーションのデバッグ] > [デバッグ シナリオ] > [Character Animator によるデバッグ (UNIX)] に進んでください。