私はvalgrind3.6.0を持っていますが、どこでも検索しても何も見つかりませんでした。
問題は、valgrindを使用しているときにfloat番号にアクセスしようとすると、セグメンテーションフォールトが発生することですが、valgrindを使用せずにプログラムをそのまま実行すると、すべてが期待どおりに実行されます。
これはコードの一部です:
class MyClass {
public:
void end() {
float f;
f = 1.23;
std::stringstream ss;
ss << f;
std::cout << ss.str();
}
};
extern "C" void clean_exit_on_sig(int sig) {
//Code logging the error
mc->end();
exit(1);
}
MyClass *mc;
int main(int argc, char *argv[]) {
signal(SIGINT , clean_exit_on_sig);
signal(SIGABRT , clean_exit_on_sig);
signal(SIGILL , clean_exit_on_sig);
signal(SIGFPE , clean_exit_on_sig);
signal(SIGSEGV, clean_exit_on_sig);
signal(SIGTERM , clean_exit_on_sig);
mc = new MyClass();
while(true) {
// Main program loop
}
}
Control + Cを押すと、プログラムは信号を正しくキャッチし、すべてが正常に動作しますが、valgrindを使用してプログラムを実行すると、このコマンドを実行しようとするとss << f; // (Inside MyClass)
、セグメンテーション違反がスローされます:-/
私もこれを試しました:
std::string stm = boost::lexical_cast<std::string>(f);
しかし、ブーストがフロート番号にアクセスしたときも、セグメンテーション違反のシグナルを受信し続けます。
これは、ブーストでセグメンテーション違反が発生したときのバックトレースです。
./a.out(_Z17clean_exit_on_sigi+0x1c)[0x420e72]
/lib64/libc.so.6(+0x32920)[0x593a920]
/usr/lib64/libstdc++.so.6(+0x7eb29)[0x51e6b29]
/usr/lib64/libstdc++.so.6(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_+0xd3)[0x51e8f43]
/usr/lib64/libstdc++.so.6(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd+0x19)[0x51e9269]
/usr/lib64/libstdc++.so.6(_ZNSo9_M_insertIdEERSoT_+0x9f)[0x51fc87f]
./a.out(_ZN5boost6detail26lexical_stream_limited_srcIcSt15basic_streambufIcSt11char_traitsIcEES4_E9lcast_putIfEEbRKT_+0x8f)[0x42c251]
./a.out(_ZN5boost6detail26lexical_stream_limited_srcIcSt15basic_streambufIcSt11char_traitsIcEES4_ElsEf+0x24)[0x42a150]
./a.out(_ZN5boost6detail12lexical_castISsfLb0EcEET_NS_11call_traitsIT0_E10param_typeEPT2_m+0x75)[0x428349]
./a.out(_ZN5boost12lexical_castISsfEET_RKT0_+0x3c)[0x426fbb]
./a.out(This line of code corresponds to the line where boost tries to do the conversion)
これは、デフォルトの文字列ストリーム変換を使用したものです。
./a.out(_Z17clean_exit_on_sigi+0x1c)[0x41deaa]
/lib64/libc.so.6(+0x32920)[0x593a920]
/usr/lib64/libstdc++.so.6(+0x7eb29)[0x51e6b29]
/usr/lib64/libstdc++.so.6(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_+0xd3)[0x51e8f43]
/usr/lib64/libstdc++.so.6(_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd+0x19)[0x51e9269]
/usr/lib64/libstdc++.so.6(_ZNSo9_M_insertIdEERSoT_+0x9f)[0x51fc87f]
./a.out(This line of code corresponds to the line where I try to do the conversion)
a.out
は私のプログラムであり、valgrindを次のように実行します。valgrind --tool=memcheck ./a.out
もう1つの奇妙なことはmc->end();
、プログラムが正常に実行されているときに電話をかけると(信号を受信し、Objectが作業を終了したばかり)、(valgrindの場合と同様に)セグメンテーション違反が発生しないことです。
「Control+Cでプログラムを閉じないでください。何とか何とか...」このコードは、セグメンテーション違反の場合にデータを失うことなく、デッドロックのためにプログラムを強制終了することなく、プログラムで発生する可能性のあるエラーをログに記録するためのものです。または、他の何か。
編集:たぶんvalgrindのバグです(私は知りません、グーグルで検索しましたが何も見つかりませんでした、私を殺さないでください)、どんな回避策も受け入れられます。
EDIT2:ブーストがostreamも呼び出すことに気づきました(ここではvimを使用するよりも明確です:-/)、sprintffloat変換を試してみます。
EDIT3:これを試しましsprintf(fl, "%.1g", f);
たが、それでもクラッシュします、バックトレース:
./a.out(_Z17clean_exit_on_sigi+0x40)[0x41df24]
/lib64/libc.so.6(+0x32920)[0x593a920]
/lib64/libc.so.6(sprintf+0x56)[0x5956be6]
./a.out(Line where sprintf is)