LinuxC言語でのセグメンテーション違反

セグメンテーション違反

主な理由は
次のとおりです。メモリアクセス違反
、無制限または深すぎる再帰処理。
調査方法ではコアダンプを使用できます。

いわゆるコアダンプとは、その時点でプログラムが使用していたメモリ空間の内容をすべてコピーし、実行中のプログラムがエラーで強制終了したときにファイルに保存する内容を指します。デバッグ作業に使用されます。

#include <stdio.h>
#include <string.h>

#define FNAME      "/home/work/coredump/aaa/xxxxxxxxxxxxxxxxxxxxxxxx/data/zzzzzzzz/testfilexxxxx.txt"
#define FNAME_NEW  "/home/work/coredump/aaa/xxxxxxxxxxxxxxxxxxxxxxxx/data/zzzzzzzz/testfilexxxxx_new.txt"

int main(void)
{
    
    
    char cmd[128];
    memset(cmd, 0, sizeof(cmd));
    sprintf(cmd, "mv -f %s %s", FNAME_NEW, FNAME);
    system(cmd);
    return 0;
}

上記のコードをコンパイルして実行すると、セグメンテーション違反エラーが報告されます

# ./a.out 
Segmentation fault

コアダンプを使用してデバッグする

以下の手順に従って調査してください

  1. コアアダプタのサイズを設定します
  2. gccの-gオプションを使用してコンパイルします(デバッグ情報の付与)
  3. 生成して実行→コアファイル
  4. gdbのコアファイルを読み取ります
  5. 原因を調査する場所

コアアダプタのサイズを設定します

最初にこのコマンドを実行します

[root@localhost coredump]# ulimit -c
0
[root@localhost coredump]# ulimit -c unlimited
[root@localhost coredump]# ulimit -c
unlimited

「Ulimit」は、システムリソースの上限を設定するコマンドのようです。
「-cオプション」は、コアダンプのサイズを設定します。
「無制限」、つまり上限はありません。

gccの-gオプションを使用してコンパイルし、生成して実行→コアファイル

通常のコンパイルに加えて、「-g」がオプションに追加されます

[root@localhost coredump]# gcc -g main.c

これにより、デバッグ情報を追加できます。コンパイルが成功した場合は、実行してみましょう。

[root@localhost coredump]# ./a.out 
Segmentation fault 

セグメンテーション違反が発生します。
ここにファイルリストを表示すると

[root@localhost coredump]# ls -l
合計 168
-rwxr-xr-x. 1 root root   9656  4月  9 17:08 a.out
drwxr-xr-x. 3 root root     38  4月  9 17:04 aaa
-rw-------. 1 root root 245760  4月  9 17:08 core.3618
-rwxrwxrwx. 1 root root    404  4月  9 17:05 main.c

「core.XXXXX」というファイルがあります。これはコアダンプファイルです

gdbのコアファイルを読み取ります

gbdはコンソール処理用のデバッガーです。このgdbを使用すると、コアダンプファイルを開くことで、セグメンテーション違反が発生したときのデバッグ情報を表示できます。

[root@localhost coredump]# gdb a.out core.3618 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.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/work/coredump/a.out...done.
[New LWP 3618]
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0x0000000000400602 in main () at main.c:15
15    }
Missing separate debuginfos, use: debuginfo-install glibc-2.17-222.el7.x86_64
(gdb) 

エラーが「main.cの15行目」にあることを意味します。詳細を確認してください

(gdb) bt
#0  0x0000000000400602 in main () at main.c:15
(gdb) frame 0
#0  0x0000000000400602 in main () at main.c:15
15  }

「q→Enter」で、gdbを終了できます

原因を調査する場所

  1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 #define FNAME      "/home/work/coredump/aaa/xxxxxxxxxxxxxxxxxxxxx    xxx/data/zzzzzzzz/testfilexxxxx.txt"
  5 
  6 #define FNAME_NEW  "/home/work/coredump/aaa/xxxxxxxxxxxxxxxxxxxxx    xxx/data/zzzzzzzz/testfilexxxxx_new.txt"
  7 
  8 int main(void)
  9 {
    
    
 10     char cmd[128];
 11     memset(cmd, 0, sizeof(cmd));
 12     sprintf(cmd, "mv -f %s %s", FNAME_NEW, FNAME);
 13     system(cmd);
 14     return 0;
 15 }   // ←这行

その理由は、アクセスが準備されたバッファを超えているためです。mvコマンドの場合、合計は171バイトであり、完全に範囲外です。

mv -f /home/work/coredump/aaa/xxxxxxxxxxxxxxxxxxxxxxxx/data/zzzzzzzz/testfilexxxxx_new.txt /home/work/coredump/aaa/xxxxxxxxxxxxxxxxxxxxxxxx/data/zzzzzzzz/testfilexxxxx.txt

この問題は、バッファサイズを増やすことで解決できます

char cmd [256];

結びの言葉

LinuxのC言語では、セグメンテーション違反が発生したため、コアダンプを使用してこの問題を解決しようとしました。
基本的に、その理由は
・メモリアクセス違反です。
・無限または深すぎる再帰処理。

おすすめ

転載: blog.csdn.net/qq_18191333/article/details/114118800