上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
 
putsをフックしてprintfでログを吐かせようと思って、↓みたいなことやってみたら、セグメンテーションフォルトで落ちた。


#include <stdio.h>

int puts(const char* str)
{
printf("abc\n");

return 0;
}

int main(int argc, char** argv)
{
puts("def\n");

return 0;
}



printfの中でputsに呼び換えでもしてて、無限再帰しちゃってるのかなと思ったけど、調べたら驚愕の事実が・・・


とりあえず、上のソースのアセンブリ出力してみると、


.LC0:
.string "abc"
.text
.globl puts
.type puts, @function
puts:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $.LC0, (%esp)
call puts
movl $0, %eax
leave
ret
.size puts, .-puts
.section .rodata


なぜか、printfじゃなくてputs呼んでます。
どうやら、末尾改行付・エスケープシーケンス無しの文字列リテラルをprintfに渡していると、gccが最適化で勝手にputsに置き換えしちゃうようです。

printfに渡すとputsに置き換えられちゃう文字列。
"~\n"


printfに渡してもputsに置き換えられない文字列。
"~"
"~%d\n"
文字列ポインタ変数


いくら標準関数とはいえ、関数の仕様に依存した最適化って・・・
やりすぎだろgcc。

ちなみにVCではこんなことは起きないみたいです。
ワーニングも吐いてくれます。

warning C4273: 'puts' : dll リンクが一貫していません。


 

<< PCの起動が遅くてふんとにうんざりしてました | Home | 特別強化の発生率 >>

コメント

コメントの投稿

URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 

トラックバック


この記事にトラックバックする(FC2ブログユーザー)


 BLOG TOP 


template and material by HPテンプレート素材集IFD
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。