url: https://atmarkit.itmedia.co.jp/ait/articles/1703/01/news173_3.html
title: "���Ȃ����m��Ȃ��v���O�����̐^�̎n�܂�\\�\\main()�֐��̑O�ɂ���X�^�[�g�A�b�v�Ƃ�"
description: "C����́uHello World�I�v�v���O�����Ŏg����A�uprintf()�v�umain()�v�֐��̒��g���A�f�o�b�K�ɂ���͂Ƌt�A�Z���u���A�\\�[�X�R�[�h�lj��Ȃǂ̂��܂��܂ȑ��ʂ���T��A�ځB����́Amain()�̒��g��A���̑O�ɌĂяo�����X�^�[�g�A�b�v�Ƃ��������������ɂ‚��Ċw�ԁB"
host: atmarkit.itmedia.co.jp
image: https://image.itmedia.co.jp/images/logo/1200x630_500x500_ait.gif
url: https://blog.masu-mi.me/post/2016/05/07/investigate_pre_main/
title: "main にたどり着く前を追ってみた • masu-mi's blog(dirty pages)"
description: "結婚式準備の気分転換とgdbの練習を兼ねてmainにたどり着くまでの動きを追った。GCCでは以下の関数を設定するとmainに入る前に実行される。123__attribute__((constructor)) void constructor(){  printf(\"constructor\\n\");}Linux環境のバイナリはELF形式が一般的で、ELFでは_startがデフォルトのエントリポイントになる。今回の整理だいたい下の事がわかったが、main の中でバックトレースを確認しても_startなどが表示されない理由がわからなかった。GCCを使うとELFのデフォルトエントリポイントは_start_startは/usr/lib64/crt1.o由来OSXはELFファイルでなく_startがリンク時に衝突する事はないGCC拡張のconstructorは__libc_csu_init()から呼ばれるmainは__libc_start_main()から呼ばれるELFのエントリポイントは変更可能だが後処理の自作が必要になる一応main 外部がバックトレースで表示されない理由は下が考えられる。スタック積み上げ動作が異なり呼び元の情報が不完全になるgdbが気を効かせてmain以降を遡らないとりあえず切り分けるには手作業でESP, EBPを追いmainから__libc_csu_init,_startに辿り着けるか確認すれば良い。そしてgdbの優しさの疑いが高まった場合に、ソースコードを読みに行けば解決しそう。ヘタレとしては面倒くさくなりそうな気がする。"
host: blog.masu-mi.me
favicon: https://blog.masu-mi.me/masu.ico

main 関数が呼ばれる前に行われる事前の設定処理を スタートアップ とよぶ。 OS が実行可能プログラムを起動するときに行う処理である。

  1. _start ラベル・関数を実行する
    1. 必ず _start をエントリポイントにするよう決められている ( ELF )
  2. _start__libc_start_main 関数を実行する
    1. __libc_start_main がやること
      1. 初期設定やグローバル変数の初期化
      2. コマンドライン引数の準備
      3. __attribute__((constructor)) 関数の呼び出し
      4. _main 関数の呼び出し
  3. __libc_start_main から _main 関数を呼び出す