質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

3800閲覧

Mac上のC++で行番号付きスタック・トレースは可能でしょうか?

Chironian

総合スコア23272

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2018/06/20 14:22

編集2018/06/21 05:09

Mac上のQtにて開発しているのですが、スタック・トレースでハマっています。
boostのStackTraceでは関数名までしか表示されず、ソース・ファイル名と行番号が表示されません。addr2lineがないためと思います。
BOOST_STACKTRACE_USE_BACKTRACEを使ってlibbacktraceも試してみたのですがlibbacktrace.laのビルドがうまく行きません。(libbacktrace.laはできますが945バイトと小さくリンクしても_backtrace_create_state等のシンボル無しエラーになる)

Posixのbacktraceも大差ないです。(マングルされた関数名とオフセットが表示されます。)

アプリが落ちた後、システムが表示するダイアログで「レポート」を押すとソース・ファイルと行番号もでるので何らかの方法で表示することは可能と思うのですが、その方法を見つけることができません。

Mac上のC++プログラムでソース名と行番号を表示するには何をすればよいでしょうか?
もしくは、Mac(High Sierra 64bit)上でlibbacktraceをビルドする方法をご存知の方はいらっしゃいませんか?(現在は、単純に./configure後にmakeしているだけです。)

次に、SIGSEGV発生時のスタック・トレースも表示したく、boostのこのページの手順でトライしています。
しかし、Macの場合、起動する度にアプリがロードされるアドレスが変わるようで、前回保存したダンプ・ファイルの関数名さえ適切に表示されません。あさってのシンボルになったり、変換されなかったりです。これに対処する方法は存在するでしょうか?


Macについては不慣れなので、多少馬鹿なことを聞いているかも知れません。ご容赦頂けると幸いです。


【追記】
記載漏れがありました。binutilsのgaddr2lineは試しています。
homebrewでインストールし、インストールされたパスをBOOST_STACKTRACE_ADDR2LINE_LOCATIONでboost stack traceへ指示してみました。
結果は変わらず、関数名までしか表示されませんでした。


【更に追記】
Twitterで拾った情報からlibbacktraceのissue Mach-O support #2を辿れました。
どうも残念ながらlibbacktraceは未だMac OSはサポートしていない様子です。

英語のニュアンスがうまく読み取れないので、誤読しているかもしれませんが、需要が少ないことと苦労が凄まじいことが原因っぽいです。このプルリク主の JohnColanduoni さんはかなり粘り強く頑張っている(Add libbacktrace support for Apple platformsAdd libbacktrace support for Apple platforms (resubmitted))ようですが、結局難易度が高すぎていまだうまく行っていないと読み取れました。

Macはクローズド・システムだから、Appleがスタックトレースを取得するAPIを公開しない限りかなり厳しいことになります。そして、このように公開の場で苦労し続けている人がいるということは、Appleはスタックトレースを取得するAPIを公開していないということかも?

kazto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

詳しくはないんですが、LLVMって使えないんですかね?
LLVM 3.1 リリースノートの訳
mac osでLLVMの環境を構築してみる
標準のLLDBでも可能なのかもしれませんが。
的外れだったらご容赦下さい。

投稿2018/06/21 01:43

編集2018/06/21 01:50
sazi

総合スコア25173

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2018/06/21 03:12

ご回答ありがとうございます。 Macの標準の開発環境(Xcode)のコンパイラはllvmですので、あまりかわらない可能性が高いと思います。 私が使っている環境の__VERSION__マクロは、"4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)"と定義されていました。 lldb調べてみましたがコアダンプが生成されず断念しました。生成される場合でもストレージ圧迫の大きな原因の1つのようですので生成するのは厳しいですが。https://goo.gl/PkicP5
guest

0

libbacktraceのビルドがうまくいかないというのはもう少し具体的にお願いいたします。
ビルド自体はエラーを吐かずに成功するのですか?

ロードされるアドレスが変わるのはASLRが有効になってるんだと思います。
以下のサイトをもとにASLRを無効にしたプログラムを作成できませんか?

ASLR

追記:
addr2lineがないのであればportでaddr2line相当のgaddr2lineがbinutilsで入れられるそうですが、入れたあとエイリアス等でaddr2lineと置き換えられませんか?
homebrewが使えるならそちらでも。

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .libs/libbacktrace.a(atomic.o) has no symbols

これは多分、

→#if !defined (HAVE_ATOMIC_FUNCTIONS) && defined (HAVE_SYNC_FUNCTIONS)

これによってatmic.oの中身がないんだと思います。
nmでシンボルが全く存在しないのか確認できますでしょうか。
多分途中抜けてる感じでも中身はあると思うのですが。

エラーで落ちるのであればリリースビルドとしてではなくデバッグビルドとして検証したほうがよろしい気がしますが・・・。
addr2lineはコンパイル時の最適化オプションはどうだか知りませんがデバッグ情報はどちらにしろ付加しないといけないみたいなので、ただ単にリリースビルドとしてビルドしただけ(デバッグ情報を付加していないのであれば)では使えないそうですが、デバッグビルドとしてビルドすることを再考したほうがよろしいかと。。。
リリースビルドで起きるエラーなのでしょうか?
最適化かかっていたらどちらにしろエラー時の情報の有用性(スタックトレースが読みにくい気がします)が低くなってしまいますが、リリースビルドじゃないとだめでしょうか・・・。

addr2lineはPIEもしくはPICでコンパイルしても駄目らしいのでどちらにしろコンパイルし直さないと正しい情報が得られないと思います。
ASLRは対象のプログラムだけ無効といった形でも駄目でしょうか?
コンパイル時にこんな感じで無効化できるかもしれません。

追記:

atmic.oをnmでみてみました。全く何も出てきませんでしたので空です。ちょっと気になってリンク・エラーになるシンボル _backtrace_create_state を探してみたところ、state.cにあり、state.oをnmでみると入ってました。

.libsにlibbacktrace.soができると思うのですが、こちらに_backtrace_create_stateはありませんか?
libbacktrace.la自体はテキストファイルでlibtoolが見るやつなので無視していいです。
こちらにあるならlibbacktraceのビルドは正常にできており、リンクが間違っているかaddr2lineが正常にデータを拾えてないことになります。

addr2lineが正常に動いているかどうかは確認いたしましたでしょうか?
該当のファイルにgccなら-no-pieをつけてコンパイルしないとaddr2lineに相対アドレスを渡すことになり、計算する必要がございます。
boostの内部の実装がどうなってるかわかりませんが、PIEで実行すると正常にデータが得られないのではないでしょうか?

投稿2018/06/20 15:24

編集2018/06/21 05:56
m_yoko

総合スコア156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2018/06/20 15:46

ご回答ありがとうございます。 libbacktrace.laができていて、かつ、error: やwarning: はでていないのでlibbacktraceのビルド自体は成功しているように見えます。 ただ、次のようなメッセージがでていますので、適切にはビルドできないと思います。 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: .libs/libbacktrace.a(atomic.o) has no symbols そのままboost stack trace経由でアプリとリンクするとシンボル無しエラーとなります。 ASLRについては理解しています。これを解除するということはセキュリティ的に弱くなるのでこれは解除しない方針です。お客様のPCで稼働中に万が一不具合が発生した時のデバッグ用ログ取得が目的なので、セキュリティ上のリスクを上げてまでやることではないと考えています。
Chironian

2018/06/21 04:14 編集

追記ありがとうございます。gaddr2lineは実はトライしています。記載せずすいません。BOOST_STACKTRACE_ADDR2LINE_LOCATIONにgaddr2lineのフルパスを定義してトライしました。残念ながら結果は変わらずでした。 atmic.oをnmでみてみました。全く何も出てきませんでしたので空です。ちょっと気になってリンク・エラーになるシンボル _backtrace_create_state を探してみたところ、state.cにあり、state.oをnmでみると入ってました。何故にこれがリンクされないのか謎です。 最終系はリリースビルドしますが、現時点ではデバッグビルドでトライしています。現在は、スタックトレースを取得するコードをデバッグしている状態なのです。これに成功してからリリースビルドにトライ予定です。 addr2lineのビルドはそれなりに手間がかかるので、希望が見えてからトライしたいです。 アSLRの解除は厳しいです。内部にWebBrowserコントロールを抱えていますし、セキュリティ上のリスクが上がる以外の手段がない場合は、スタック・トレースを断念する方向です。
Chironian

2018/06/21 06:37

更に追記ありがとうございます。 おおっ、.libsにlibbacktrace.dylibがありました!!(Macなので.soではなく.dylib) 同じところに、libbacktrace.aも有ったので、こちらとリンクしてみます。(ただ、質問に追記したようにlibbacktraceがMacをサポートしているかどうか怪しいです。でも、.dylibがあるならできてもよさそうですし。) なお、addr2lineとlibbacktraceは排他です。2つの仕組みをboostがサポートしていてどちらかを選択します。
Chironian

2018/06/21 07:06

やってみましたが、結論としてはダメでした。 libbacktraceの方はリンクし、起動することにも成功しました。しかし、関数名さえ表示されなくなりました。 gaddr2lineは、直接コマンドラインにて、「gaddr2line -e 実行ファイル 0x上記で表示されたアドレス」としても ??:0 と表示されるだけでした。 やはり無理っぽいですね。 ところで、m_yoko さんは、MacにてC++プログラムでスタックトレースのファイル名と行番号を獲得するのに成功されたことがある、もしくは、成功したとの話を聞いたことはございますか? 質問に追記した内容から、安定して使える方法はないのではないかと疑っています。
m_yoko

2018/06/21 07:55

PIEで実行しているならば自分で計算し直さないとaddr2lineは使えないですが、アドレスは再計算したでしょうか? objdumpして実際に該当のアドレスは見てみましたか? 少なくともobjdumpで出力されるアドレスに該当の箇所がないと出力されないはずです。 相対のアドレスの方を入力すると出ます。 こちらではLinuxマシンしかないため、Linux上でやってますが、セグフォしたときの+0x65eとかのアドレスを打ち込むと出ました。右側のメモリ上のアドレスは毎回変わるんで打ち込んでも駄目です。 Backtrace: ./main(+0x65e)[0x55899d56465e] ./main(+0x6a6)[0x55899d5646a6] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7f22d57f11c1] ./main(+0x56a)[0x55899d56456a] 一度PIEでコンパイルするのをやめて試してみたらどうでしょうか? 周りはSwiftの開発者はいるのですがC++でやってる人が居ないので聞いたことないですね。。。
Chironian

2018/06/21 09:11

「アドレスは再計算」はしていないというか、再計算方法は把握していません。 といいますか、私がgaddr2lineに与えた数値はboost stack traceの出力ですので、ASLRやPIC/PIEを想定した場合、これがそもそも相対アドレスでないとソース名と行番号へ変換できる筈がないですね。 ということは、boostの出力が相対アドレスでない、もしくは、boostのスタックトレースはgaddr2lineと非互換ということになります。ASLR絡みの動作から前者と思います。どちらにせよ、この問題は私が対処できる気がしません。 > 一度PIEでコンパイルするのをやめて試してみたらどうでしょうか? そもそもMacで非位置独立コードって可能なのでしょうか?(結構難易度高そうな印象です。) https://stackoverflow.com/questions/26647563/is-it-possible-to-make-non-fpic-dylib-in-mac http://wwweic.eri.u-tokyo.ac.jp/computer/manual/altixuv/doc/Compiler/fort/jp_lnx_fortdocs11.1.tar/Documentation/ja_JP/compiler_f/main_for/copts/common_options/option_fpie.htm そして、またまたすいません。明記しておくべきでしたが、boost stack traceは、Windowsとlinuxではソース名と行番号まで表示できます。Macだけダメなのです。 質問の追記に簡単ですが記載しましたように、libbacktraceに2年前にプルリクが投げられて採用されず、そこでrust専用としてプルリクされ、それも結局採用されていないという事実は重いです。(Appleが必要なAPIを公開していないのではないか?と私は感じています。) Macでソース名と行番号をプログラムにて獲得できるとの情報をお持ちでないのであれば、この辺で終了させて頂ければ幸いです。
m_yoko

2018/06/21 09:59

最新のMacではデフォルトでPIEが有効になっているそうですよ。 https://jp.xlsoft.com/documents/intel/compiler/18/cpp_18_win_lin/GUID-EFCC2954-F3C9-4A85-A227-62B30A077109.html http://www.oversea-pub.com/category/free/c https://stackoverflow.com/questions/23897963/documented-way-to-disable-aslr-on-os-x https://stackoverflow.com/questions/10562280/line-number-in-google-perftools-cpu-profiler-on-macosx 実際にPIEが有効になっているかはotoolを使ってフラグを見てみればわかると思いますが・・・。 有用な情報を提供できず申し訳ございません・・・。
Chironian

2018/06/21 17:38 編集

追加情報ありがとうございます.非位置独立コード(非PIE)ってできるのですね。ALSRがディセーブルされるので本番では使えないですが、試しにやってみました。 が、ダメでした。libbacktraceはアドレスしか表示されず、デフォルトとgaddr2lineは関数名までしか表示されませんでした。 残念な結果でしたが、お付き合いありがとうございました。
guest

0

自己解決

この件、少なくともメジャーな解決方法は存在しないという結論になると思います。
無いものの証明はできないので、「メジャーな方法は存在しない」にてクローズとさせて頂きます。

投稿2018/06/24 04:57

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問