質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

MinGW

MinGW(ミン・ジー・ダブリュー)は GNUツールチェーンのWindows移植版です。 ランタイムライブラリと開発ツールで構成されています。

Q&A

解決済

2回答

1561閲覧

MingwのGCCにて、-fstack-protectorを使ったC言語プログラムの実行時セグメンテーションエラーの原因について

kolona

総合スコア16

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

MinGW

MinGW(ミン・ジー・ダブリュー)は GNUツールチェーンのWindows移植版です。 ランタイムライブラリと開発ツールで構成されています。

0グッド

0クリップ

投稿2019/06/27 14:02

前提・実現したいこと

・MingwのGCCにて、-fstack-protectorを使った際のセグメンテーションエラーについて原因を知りたいです。

・また、-fstack-protector以外に、デバッグ(特にメモリ破壊のチェック)に役立つものがありましたらご教授ください。(現在のMingwでは、mudflap は「gcc.exe: warning: switch '-fmudflap' is no longer supported」と拒否されます。ValgrindはWindowsに対応していないようです。)

発生している問題・エラーメッセージ

(元々は別の問題を解決するために)Mingwの最新版で、C言語のソースコードを-fstack-protector-all 指定してコンパイルしたところ、プログラム開始直後に
Program received signal SIGSEGV, Segmentation fault.
が発生します。
検証用のシンプルなプログラムでも同様の問題が発生するため、-fstack-protector-all の使い方?に問題があると考えています。

以下のコードを、次のコンパイルオプションでコンパイル、リンクしています。

コンパイルコマンド1
gcc -std=gnu99 -DUNICODE -D_UNICODE -Ddebug -g3 -O0 -static -Wextra -ftrapv -Wshadow -Wstrict-prototypes -Wmissing-declarations -Winit-self -Wswitch-default -Wswitch-enum -Wfloat-equal -Wcast-align -Wsign-compare -fstack-protector-all -ftrapv -Wall -Wuninitialized -s -c -o debug_tst.obj debug_tst.c

コンパイルコマンド2
gcc -std=gnu99 -static -fstack-protector-all -o debug_tst.exe debug_tst.obj

リンク
gcc -std=gnu99 -g3 -static -fstack-protector-all -ftrapv -o debug_tst.exe debug_tst.obj

該当のソースコード

C言語

1#include <stdio.h> 2#include <tchar.h> 3 4int funct(int a, int b); 5 6int funct(int a, int b){ 7 8 int c; 9 // 無意味な処理です 10 a = b; 11 c = a + b; 12 13 return c; 14} 15int main(int argc, char **argv){ 16//int _tmain(int argc, TCHAR **argv){ 17 18 int a, b, c; 19 20 if( argc>2 || argv==NULL ) return 1; 21 22 a = 1; 23 b = 2; 24 25 c = funct( a, b); 26 _tprintf( _T("c=%d\n"), c ); 27 28 return 0; 29} 30

試したこと

GDBで実行した場合、次のように即死します。

(gdb) run
Starting program: D:\work\debug_tst.exe
[New Thread 4868.0xda4]

Program received signal SIGSEGV, Segmentation fault.
0x0040147a in main (argc=1, argv=0x2d0f40) at debug_tst.c:18
18 int main(int argc, char **argv){
(gdb) bt
#0 0x0040147a in main (argc=1, argv=0x2d0f40) at debug_tst.c:18
(gdb) frame 0
#0 0x0040147a in main (argc=1, argv=0x2d0f40) at debug_tst.c:18
18 int main(int argc, char **argv){
(gdb) disp argc
1: argc = 1
(gdb) disp argv[0]
2: argv[0] = 0x2d1528 "D:\work\debug_tst.exe"

このように、バックトレースしてもほとんど何の情報もありません。
コンパイルオプションをできる限り削っていくと、-fstack-protector-all があるときだけ即死するようなのですが、バグの入るようなソースでもない上、そもそもmain()に入った途端にSegmentation faultというのが理解に苦しみます。
stack-protectorにバグがあるとは思えませんが、使用法の問題でしょうか?
なお、この機能については、「Binary Hacks(オライリー・ジャパン)」の
P168 HACK#46 -fstack-protector でスタックを保護する
を参考にしています。

補足情報(FW/ツールのバージョンなど)

開発環境

Win7 Home 32bit
gcc version 8.2.0 (MinGW.org GCC-8.2.0-3)
GNU gdb (GDB) 7.6.1

stack-protectorのバージョンは、次のように表示されています。
sspライブラリ

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/06/28 03:38 編集

gccは32ビットバージョンですか? コンパイルオプション付けない時は正常に実行できるのですか?
kolona

2019/06/28 00:56

はい。gccは32bitバージョンで、他のプログラムは一応正常に実行はできる設定です。 -fstack-protectorをつけなければ、警告もなくビルドでき、実行すれば正常終了します。
guest

回答2

0

ベストアンサー

Windows固有のヘッダファイル(tchar.h)や定義(_tprintf( _T("c=%d\n"), c );)を使っているのは?
当方Windows環境がないのでわからないのですが、上記2箇所をコメントアウトして printf( "c=%d\n", c );に書き換えコンパイル&実行した所正常に動作しました。
当方の環境↓
Linux Mint191 5.0.0-19-generic
gcc-8 (Ubuntu 8.3.0-6ubuntu1~18.04.1) 8.3.0
結果:

text

1usr ~/Project/test % gcc -std=gnu99 -static -fstack-protector-all t2.c 2usr ~/Project/test % ./a.out 3c=4 4usr ~/Project/test % echo $? 50 6usr ~/Project/test % cat t2.c

c

1#include <stdio.h> 2//#include <tchar.h> 3 4int funct(int a, int b); 5 6int funct(int a, int b){ 7 8 int c; 9 // 無意味な処理です 10 a = b; 11 c = a + b; 12 13 return c; 14} 15int main(int argc, char **argv){ 16//int _tmain(int argc, TCHAR **argv){ 17 18 int a, b, c; 19 20 if( argc>2 || argv==NULL ) return 1; 21 22 a = 1; 23 b = 2; 24 25 c = funct( a, b); 26// _tprintf( _T("c=%d\n"), c ); 27 printf( "c=%d\n", c ); 28 29 return 0; 30}

usr ~/Project/test %

投稿2019/06/28 01:35

cateye

総合スコア6851

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cateye

2019/06/28 01:47 編集

tchar.hは環境に合わせて文字コード(sjisやutf-8など)を設定するヘッダだと思いましたが・・・違てたらごめんなさい。 不要であればincludeしないほうが、原因がつかみやすいかと思います。
kolona

2019/06/28 03:23

ありがとうございます。 はい、ご指摘の通り、内部でUNICODEを使うために使用していました。 ご指摘を受けてワイド文字に関する記述を削除し、printfにしてみましたが、やはり全く同じところでSegmentation faultしました。 gcc -std=gnu99 -Ddebug -g3 -O0 -static -fstack-protector-all -Wall -s -c -o debug_tst_sjis.obj debug_tst_sjis.c でコンパイル、 gcc -std=gnu99 -g3 -static -fstack-protector-all -o debug_tst_sjis.exe debug_tst_sjis.obj でリンクしています。 -fstack-protector-all を指定しないでビルドするとGDB上でも exited normallyで終了することも同様でした。
cateye

2019/06/28 03:36 編集

残念ながらこちらでは再現しませんね? ----->8----->8----->8----->8----->8----->8----->8----->8----->8----- usr ~/Project/test % gcc -std=gnu99 -Ddebug -g3 -O0 -static -fstack-protector-all -Wall -s -c t2.c usr ~/Project/test % gcc -std=gnu99 -g3 -static -fstack-protector-all t2.o usr ~/Project/test % ./a.out c=4 usr ~/Project/test % gdb ./a.out GNU gdb (Ubuntu 8.2-0ubuntu1~18.04) 8.2 Copyright (C) 2018 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-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./a.out...done. (gdb) run Starting program: /home/kondo/Project/test/a.out c=4 [Inferior 1 (process 4222) exited normally] (gdb) quit usr ~/Project/test % ----->8----->8----->8----->8----->8----->8----->8----->8----->8----- Windows(MinGW?)固有の問題かも?
kolona

2019/06/28 04:37

ありがとうございます。 他環境では大丈夫という情報から、まさかと思い過去版のMingwのバックアップデータ(gcc version 6.3.0) を使用して同じ操作をしたところ、なんと正常終了してしまいました。 libssp.aがライブラリ本体と思いますが、 旧版(gcc 6.3.0)10.9 KB (11,252 バイト) 新版(gcc 8.2.0)12.4 KB (12,762 バイト) と相違しているようです(内容はわかりませんが)。 Mingw版のみのバグの可能性が出てきました。 もう少し検討してみます。 >>Code::Blocks 情報ありがとうございます。 試しに入れてみようと思います。
guest

0

解決には至りませんでしたが、問題の箇所、対策はある程度判明したのでまとめておきます。

問題の原因
-fstack-protectorオプションで libssp.a 等を利用する際の、オブジェクトファイルの作成にそもそも失敗している。つまり、原因の一つは、gccによる処理のミスと思われる。

対策(確実ではありません)
32bit Windows OSで-fstack-protector 特に-fstack-protector-all を使わない。既にサポートが終了しようとしているWin7 の32bit OS はバグフィックスも遅いのかもしれない。特に、後述するように-fstack-protectorはスタックのローカル変数前後にカナリア値を入れたり、ガード値のチェック?などを行うため、OSのbitが32bitか64bitかが重要っぽいです。

試したこと
0. mingw-w64シリーズの導入
→ 変化無し。-fstack-protector-allでセグフォ。

  1. MinGW Installation Manager で入手したgcc6.3.0の

libssp.a、libssp.dll.a、libssp_nonshared.a を
gcc8.2.0と置き換えてみる
→ gcc8.2.0を使っている限り常にセグフォ。

  1. gcc 6.3.0 で作ったオブジェクトファイルを、gcc 8.2.0 でリンク

→DLL?エラーは出るものの、実行は可能。
0. gcc 8.2.0 で作ったオブジェクトファイルを、gcc 6.3.0 でリンク
→セグフォ。

  1. アセンブリ出力の比較

アセンブラは全く読んだことがないので注釈は一部間違っているかもしれませんが、比較するとこんな感じでした。左から順に「gcc6.3.0で-fstack-protector-all使用」「gcc6.3.0で単純コンパイル」「gcc8.2.0で-fstack-protector-all使用」
となります。
イメージ説明
見たところ特にgcc6とgcc8でアセンブラソースレベルでの大きな違いは見当たりません。にもかかわらず「gcc6.3.0で-fstack-protector-all使用」では起こらないセグメンテーションエラーが「gcc8.2.0で-fstack-protector-all使用」で起こるということは、gccのここ以外での内部処理に問題があるのではないかと思うわけです。そして、前述の通りリンクされるライブラリを挿げ替えても結果は変わりません。

というわけで、セグメンテーションエラーが起こる絶対条件はgcc 8.2.0 でのコンパイルで、ライブラリは直接は関係ないようです。
無念でありますが、個人のプログラマがいじれる難易度をオーバーフローしている感じなので、以上を結果といたします。

別環境で試してくださった回答者様に感謝いたします。

投稿2019/06/30 16:36

kolona

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問