私が長いこと前に書いたライブラリを使用しようとしていたとき、私は奇妙な動作を見つけました。主な問題は、プログラムがFedora 25で実行され、LD_PRELOADを使用して自分のライブラリにリンクされていると、セグメンテーションフォルトが発生することです。私は問題を簡単に理解するために私の古い図書館の小さなサンプルを作った。Fedora 25でLD_PRELOADを使用するとセグメンテーションフォールトが発生する
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
extern void *__libc_malloc(size_t size);
void *malloc(size_t size)
{
void *ptr = __libc_malloc(size);
fprintf(stdout, "Malloc(%d)->(%p)\n", (int) size, ptr);
return ptr;
}
このコードは、これらのパラメータを使用してコンパイルされた:
gcc -c -fPIC -O3 -Wall -o libtest.o libtest.c
gcc -shared -o libtest.so libtest.o
次のようにプログラムが実行された:
LD_PRELOAD=./libtest.so ./progtest
私が "関数fprintf" 行が引き起こしたことが判明Segfaultの問題"stdout"ファイル記述子を "stderr"に変更しましたが、問題はなくなりました。
それから私は、CentOSの7を実行している別のマシン上で「 fprintfの」のための出力として「STDOUT」ファイルディスクリプタを使用して同じコードをテストし、それが「標準出力」を使用して、両方のケースで罰金働いて、 "stderr"。
これらの結果を観察することで、私は何が欠けているのか、なぜこれが起こっているのだろうかと思います。 Fedoraの25にインストール
のglibcとGCCバージョン:
のCentOS 7にインストールGNUのLDバージョン2.26.1-1.fc25
GCC(GCC)6.3.1 20161221(6.3.1-1レッドハット)
のglibcとGCCバージョン:
GNUのLDバージョン2.25.1-22.base.el7
GCC(GCC)4.8.5 20150623(レッドハット4.8.5-11)
別のアプローチは、関数fprintfを使用して捨てることであり、呼び出し:
あなたは、このような(C11)としてフラグをリエントラントを防止することができますsnprintfによって作成されました – nos
@nosそれはうまくいく可能性がありますが、私は 'snprintf'が割り振りを伴うかもしれないことにはまだ注意が必要です。 – ephemient