8

私は現在、数百のコード ファイルといくつかのサードパーティ ライブラリへの依存関係を含むプロジェクトを Mac OS に移植しています。最終的に、プログラムが警告やエラーなしでコンパイルされるようになりましたが、独自のメイン関数を実行しているようには見えません。

代わりに、サードパーティに属していると思われる他の主な機能を実行しているようです。この関数は、診断用のデータをコンソールに書き込み、その後終了します。

(gdb) continue
Current language:  auto; currently c++
//
// This is an automatically generated file.
// Do not edit.
//

const unsigned short expTable[] =
{
    0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 
...
    0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 0x3c00, 
};

Debugger stopped.
Program exited with status value:0.

スタック トレースは有効に見えますが、gdb は各スタック エントリの正しい行番号とファイル名を表示しないため、デバッガを使用してこのメ​​イン関数が存在する場所を見つけることができません (詳細については、この未解決の質問を参照してください)。

検索が完了するまでに数分かかりましたが、結果は返されませんでした。

私のプロジェクトは他のライブラリの中でも SDL を使用していますが、私は SDL_Main() とその根本的な問題を認識しており、完全に機能する SDL プロジェクト テンプレートの上にプロジェクトを構築しました。したがって、私自身のメイン関数が有効であると確信しています。

何がうまくいかないのか分かりますか?現在、不正なメイン関数を見つけて削除する方法についてのアイデアがありません。

ありがとう、

エイドリアン

編集:私が見つけたように、「これは自動的に生成されたものです」という文字列でファイルファイルを検索する際に間違いを犯しました。同じ文字列を持つ数十のファイルを見つけました。これらはすべて、私が使用しているサードパーティ ライブラリの 1 つである FreeImage に属しています。ということで、問題は FreeImage に関係しているようですが、同封の MacOs makefile で Freeimage をライブラリとしてコンパイルし、ライブラリのみをインクルードしたので、どうすればよいかまだわかりません。FreeImage の新しいバージョンを再構築して、問題が解決したかどうかを確認します。

4

10 に答える 10

8

main() が呼び出される前に失敗する静的オブジェクトの初期化子でしょうか?

于 2009-03-05T12:22:15.563 に答える
3

バイナリにいくつかのメインがありますか?使っnmてみてください。(重複とリンクしないため、可能ではないはずldですが、動的ライブラリに移動してそこで探します_main

nm a.out | grep -5 _main

_mainこれにより、バイナリで見つかったものの前後に5行が表示されます。a.out

複数ある場合は、それらがどの部分にあるかについてのヒントについて、周囲の記号を参照してください...

次のステップは、使用される各動的ライブラリで同じことを行うことです。使用されているダイナミックライブラリのリストを取得するには、 otool

otool -L a.out
于 2009-03-05T13:33:35.580 に答える
2

もう一方を見つける方法はわかりませんが、独自のエントリ ポイントを明示的に指定して、もう一方を未使用にすることができます。GNU リンカのld -e オプションを使用して、エントリ ポイントを設定できます。

-e エントリ

--entry=エントリー

デフォルトのエントリ ポイントではなく、プログラムの実行を開始するための明示的なシンボルとしてエントリを使用します。エントリという名前のシンボルがない場合、リンカはエントリを数値として解析し、それをエントリ アドレスとして使用しようとします (数値は基数 10 で解釈されます。基数 16 の場合は先頭に 0x を使用できます。基数 8 の先行 0)。

今後の読者のために、Windows でこの問題が発生した場合。同等のリンカー オプションは/ENTRYです。

于 2009-03-05T12:24:46.743 に答える
1

インクルードするヘッダー ファイルを調べて、別のmainものに再マップする定義がないかどうかを確認します。これは、セットアップを行うためにライブラリのメイン関数が最初に呼び出されるようにするための古いトリックです。通常、再定義された値を参照して、最終的にメイン関数を呼び出します。

于 2009-03-05T12:25:52.120 に答える
1

簡単なハック:

readelf -s -w my_bin_file > temp.txt

temp.txt を開き、main を検索します (1 列に FUNC があります)。最初の FILE 列が見つかるまで上に移動します。これはリンクされた main を含むファイルです。

編集:これは GNU Unix フレーバーとフレンドでのみ機能します。OS X は、ELF ではなく Mach-O 形式を使用します。

于 2009-03-05T12:30:13.093 に答える
1

実行可能ファイルを実行しようとしましたnmか? 何かヒントになるかもしれません。という名前の複数のグローバルに表示される関数とプログラムをリンクすることは可能だとは思いませんが、それがmain()どのように行われるかはわかりません。

于 2009-03-05T12:06:55.427 に答える
0

別のメモ。

WxWidgetsは独自のウィジェットも定義しますmain

ここから

すべてのプログラムと同様に、「メイン」機能が必要です。wxWidgetsでは、mainはこのマクロを使用して実装されます。このマクロは、アプリケーションインスタンスを作成し、プログラムを起動します。

IMPLEMENT_APP(MyApp)

于 2009-03-05T13:39:47.530 に答える
0

Cでは、メイン関数の前に別のエントリポイントを呼び出すことができることを知っています。これはアイデアになる可能性があります。コードは通常次のようになります。

void __attribute__ ((constructor)) my_main(void);

おそらく、コード内でそのようなものを検索できます。

C では、メイン関数をキャッチして「実際の」メインの後に呼び出すさまざまな方法もあります。一部のスレッドライブラリには、環境、スケジューラなどを「準備」するために、この種のハックがあります。

これはあまり役に立ちませんが、メインがまったく呼び出されない理由を説明できるかもしれません。

お役に立てれば!

于 2009-03-05T12:45:44.087 に答える
0

b44ExpLogTable.cppというファイルをバイナリまたはサードパーティのライブラリにコンパイルできるようです。その小さなプログラムは exp() テーブルを生成するように見えますが、どういうわけかプロジェクトにインポートされるようになりました

これとこれをFreeImageソースで参照してください

于 2009-03-06T11:04:07.690 に答える