下記のようなコードはスタック破壊します。
void
my_substr(char **dst, char *str, size_t oft, size_t len)
{
*dst = (char *)malloc(len + 1);
memcpy(*dst, (str + oft), len);
*(dst + len) = '\0';
return;
}
main()から直接呼んだ程度ならその場でセグメント違反となってくれるのでいいのですが、呼ばれる位置が深いと、(処理系によるかもしれませんが)上位関数のスタック領域を上手に壊してくれて別の箇所で異常動作しているように見えるため、原因特定が困難になる場合があります。
このようなバグを簡単に見つけられるような方法や、最近のLinuxで手軽に使えるツールなどを教えてください。
#サンプルコードそのものに対する突っ込みはご容赦ください、説明のため簡略化しているだけですので
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
いわゆる「単体テスト」とかでいけそうな気がするんだけど....
ありがとうございます。
おっしゃることは全く同感で、プログラマには同じことを言いました。
状況としては、
・これまで普通に動いていたように見えたデーモンプログラムが突然落ちたという報告
・実行バイナリ
・落ちたときのスタックトレース
・1万行弱のソースコード
だけの情報が渡され、ここから原因を探れと。
スタックトレースを見ると不自然な落ち方をしていることからスタック破壊だろうとはすぐに想像はつきました。最終的にはコードレビューで原因を特定したのですが、もっと楽に原因箇所の絞り込みができないものかと思った次第です。
No.2
- 回答日時:
私自身にも「このようなバグを簡単に見つけられるような方法や、ツールなど...」は思い当たりません。
ポインタを一旦使えば、何処かで想定外の領域を指定してしまう可能性は常にあるわけで、自分で気をつける以外にないのではないでしょうか。
あるいはC言語を止めて、C++に移行する(それでも保証できるわけではありませんが)ことでしょうか。
ありがとうございます。
やはり難しそうですか。他の情報も待ってみます。
>ポインタを一旦使えば、何処かで想定外の領域を指定してしまう可能性は常にあるわけで、自分で気をつける以外にないのではないでしょうか。
そこを補助してくれるのが、ヒープ領域に関してはElectricFenceやvalgrindが結構強力なツールだと思っています。gdbだけだと上手く動いていない現場周辺から探るしかないため、重宝しています。
No.1
- 回答日時:
ご質問者様が仰る「スタック破壊」とは具体的にどのコードを指しているのでしょうか。
但し、如何にも「ヒープメモリをfree()せずに乱費していそうな」コードに見えます。私自身はヒープメモリに関するトラブルを除くため、オープンソースの"valgrind"を利用しています。
ありがとうございます。
>ご質問者様が仰る「スタック破壊」とは具体的にどのコードを指しているのでしょうか。
ここです。
*(dst + len) = '\0';
正しくは、
*(*dst + len) = '\0';
です。
>"valgrind"を利用しています。
valgrindでは、残念ながらこのバグを検出することはできませんでした。もしかしたらオプションによっては検出できるのかもしれませんが、上手く使いこなせていません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# sprintf()の使い方について 1 2022/08/17 16:16
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- C言語・C++・C# 略語の読み方について 2 2023/05/25 12:35
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・「黒歴史」教えて下さい
- ・2024年においていきたいもの
- ・我が家のお雑煮スタイル、教えて下さい
- ・店員も客も斜め上を行くデパートの福袋
- ・食べられるかと思ったけど…ダメでした
- ・【大喜利】【投稿~12/28】こんなおせち料理は嫌だ
- ・前回の年越しの瞬間、何してた?
- ・【お題】マッチョ習字
- ・モテ期を経験した方いらっしゃいますか?
- ・一番最初にネットにつないだのはいつ?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・2024年に成し遂げたこと
- ・3分あったら何をしますか?
- ・何歳が一番楽しかった?
- ・治せない「クセ」を教えてください
- ・【大喜利】【投稿~12/17】 ありそうだけど絶対に無いことわざ
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・集合写真、どこに映る?
- ・自分の通っていた小学校のあるある
- ・フォントについて教えてください!
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・10代と話して驚いたこと
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
newしないオブジェクトについて
-
allocってなんですか?
-
c言語のポインタへの文字列入力...
-
mallocで確保するメモリの領域...
-
malloc呼び出し時のセグメンテ...
-
構造体でchar name[]と*nameの...
-
ヒープメモリの解放について
-
メモリ確保エラー時の効率的な...
-
C++で、メンバもヒープに確保さ...
-
Win32APIでのメモリ管理について
-
void*型のデータサイズ
-
DLLのマルチスレッドの動作につ...
-
Accessで、メモリを開放するタ...
-
指定したメモリアドレスの値の...
-
HeapReAllocについて
-
new と malloc によるメモリの...
-
callocの処理速度
-
スタック破壊の上手な見つけ方...
-
デストラクタを呼びたい
-
ポインタのポインタの初期化法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語のポインタへの文字列入力...
-
allocってなんですか?
-
ヒープメモリの解放について
-
newしないオブジェクトについて
-
スタック破壊の上手な見つけ方...
-
stringの最大サイズ
-
配列の添え字の最大数とは?
-
malloc呼び出し時のセグメンテ...
-
void*型のデータサイズ
-
DLLのマルチスレッドの動作につ...
-
C++で、メンバもヒープに確保さ...
-
プログラムが途中で強制終了し...
-
C++のnewで確保したメモリーの...
-
構造体でchar name[]と*nameの...
-
大容量の静的な確保の限界値
-
CでOpenMP、パラレル内での共有...
-
LPWSTRのコピー
-
C言語 mallocとfreeについて
-
ビットをローテートするプログ...
-
Accessで、メモリを開放するタ...
おすすめ情報