店員も客も斜め上を行くデパートの福袋

下記のようなコードはスタック破壊します。
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件)

いわゆる「単体テスト」とかでいけそうな気がするんだけど....

    • good
    • 0
この回答へのお礼

ありがとうございます。

おっしゃることは全く同感で、プログラマには同じことを言いました。

状況としては、
・これまで普通に動いていたように見えたデーモンプログラムが突然落ちたという報告
・実行バイナリ
・落ちたときのスタックトレース
・1万行弱のソースコード
だけの情報が渡され、ここから原因を探れと。

スタックトレースを見ると不自然な落ち方をしていることからスタック破壊だろうとはすぐに想像はつきました。最終的にはコードレビューで原因を特定したのですが、もっと楽に原因箇所の絞り込みができないものかと思った次第です。

お礼日時:2021/03/03 02:07

私自身にも「このようなバグを簡単に見つけられるような方法や、ツールなど...」は思い当たりません。


ポインタを一旦使えば、何処かで想定外の領域を指定してしまう可能性は常にあるわけで、自分で気をつける以外にないのではないでしょうか。

あるいはC言語を止めて、C++に移行する(それでも保証できるわけではありませんが)ことでしょうか。
    • good
    • 0
この回答へのお礼

ありがとうございます。
やはり難しそうですか。他の情報も待ってみます。

>ポインタを一旦使えば、何処かで想定外の領域を指定してしまう可能性は常にあるわけで、自分で気をつける以外にないのではないでしょうか。

そこを補助してくれるのが、ヒープ領域に関してはElectricFenceやvalgrindが結構強力なツールだと思っています。gdbだけだと上手く動いていない現場周辺から探るしかないため、重宝しています。

お礼日時:2021/03/02 12:22

ご質問者様が仰る「スタック破壊」とは具体的にどのコードを指しているのでしょうか。

但し、如何にも「ヒープメモリをfree()せずに乱費していそうな」コードに見えます。

私自身はヒープメモリに関するトラブルを除くため、オープンソースの"valgrind"を利用しています。
    • good
    • 0
この回答へのお礼

ありがとうございます。

>ご質問者様が仰る「スタック破壊」とは具体的にどのコードを指しているのでしょうか。

ここです。
*(dst + len) = '\0';

正しくは、
*(*dst + len) = '\0';
です。

>"valgrind"を利用しています。

valgrindでは、残念ながらこのバグを検出することはできませんでした。もしかしたらオプションによっては検出できるのかもしれませんが、上手く使いこなせていません。

お礼日時:2021/03/02 11:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報