[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[FDclone-users:01032] Re: 64bit Solaris(SPARC)環境下でのSiganl-11エラー
- Subject: [FDclone-users:01032] Re: 64bit Solaris(SPARC)環境下でのSiganl-11エラー
- From: Hiroshi Kurokawa <hiroshi-k@brain.riken.jp>
- Date: Wed, 30 Oct 2013 00:36:25 +0900
お世話になっております、黒川です。
>> > >> if (w > 0) {
>> > >> int n;
>> > >>
>> > >> cp = (char *)&def_num(i);
>> > >> for (n = 0; n < sizeof(int); n++)
>> > >> cp[n] = cp[w + n];
>> > >> }
>> > このコードをmemmoveの代わりに置いて、トレースしてみました。
>> > 結果としては、一番最初のcp[n] = cp[W + n];の箇所で落ちました。
>>
>> 一個目ということは n = 0, w = 4 ですから cp[0] = cp[4]; で
>> 落ちてるんですね?参照か代入かどっちで蹴られてるんでしょうね。
>> cp[n] = 0; にすると?n = cp[w + n]; では?
for(n = 0; n < sizeof(int); n++){
int test2;
cp[n] = 0;
または
test2 = cp[w + n];
}
としてトレースしてみました。
cp[n] = 0;のときは1回目から落ちますが、
test2 = cp[w + n];ではsignal-11は発生しませんでした。
ただし、次はshell.cのenrtyhist関数、
if(!histry[n][i]) continune;
のところでsignal-11が発生して、結局停止します。
>> cp[0] も cp[4] も dword 境界なので alignment 違反はなさそ
>> うです。だとすると本当に領域違反?char * 幅が構造体の中でだ
>> け異なるサイズになる特殊事情でもあるんでしょうか。
>>
>>
>> > ためしに、
>> > int n;
>> > long test = sizeof(def_num(i));
>> > cp = (char *)&def_num(i);
>>
>> def_num() はマクロで (int) でキャストしてありますから、そ
>> の実体が何であっても必ず sizeof() は 4 になります。なのでこ
>> の試行は無意味です。
>> def_num() で参照している変数実体は envlist[n].def で、これ
>> は char * で宣言された構造体要素です。sizeof(char *) = 8 な
>> ので、cp[4] は十分に領域範囲内の筈です。
>> def_num(i) ではなく実体の envlist[n].def の sizeof() は幾
>> らになります?これが 8 でないのなら、sizeof(char *) が文脈に
>> よりころころと変わることになって収拾がつきませんね。
この部分なのですが、
私の環境では、custom.cのマクロ定義部分で、
#ifdef FORCEDSTDCの部分が生きているらしく、
def_num(n) は envlist[n].def.numに展開されるようです。
FORCEDSTDが生きていなければ (int)envlist[n].defなのですが。
それぞれのsizeofを採ってみますと、
sizeof(envlist[i].def) = 8
sizeof(envlist[i].def.num = 4
となっているようです。
>>
>> もしくは、この envlist[n].def を (int) でキャストした時点
>> で 4byte 幅の領域に複製を用意して、cp は実はその複製の方を示
>> しているとかいう話かも知れません。
>> 例えば往年の DOS エクステンダ環境では、拡張メモリを直接ア
>> クセス出来ないために、逐一コピーを作成して疑似的にアクセスさ
>> せていました。それに似た話があるのかも。
>> だとすると、def_num(i) を def_str(i) に書換えればうまく行
>> く筈です。こちらは (int) のキャスト無しなので実体そのものの
>> ebvlist[n].def を指しています。
cp = (char *)&def_str(i)
for(n = 0; n < sizeof(int); n++)
cp[n] = cp[w + n];
としてトレースした場合、やはり一番最初で落ちました。
>>
>> あと考え得る可能性としては、構造体の最適化のために妙な配置
>> をさせていることでしょうか。
>> 一般に、構造体に char * 型の要素を宣言すると、構造体の中に
>> はポインタのみ用意してその先の実体は別領域に確保されます。こ
>> れは char * が const char * であっても同じことです。
>> しかし、const char * の場合は実体を直接構造体領域内に確保
>> する実装があったとしたらどうでしょう?64bit 環境の 8byte も
>> の長大ポインタなら結構な長さの文字列を格納可能です。
>> この場合は、実体である文字列長に応じて確保されるサイズが変
>> 化します。実体は (char *)d (d は数値) として代入されているの
>> で、アドレス d を見に行ってその中身をコピーして来るとか?
>> envlist[i] を一エントリ分ダンプさせてみるとどうなるんでし
>> ょうかね?printf() だとこんな感じ。
>> {
>> int n;
>>
>> cp = (char *)&(envlist[n]);
>> for (n = 0; n < sizeof(envtable); n++)
>> printf("%02x ", cp[n] & 0xff);
>> }
>>
cp = (char *)&(envlist[i]);
for(n = 0; n < sizeof(envtable); n++){
printf("%02x ", cp[n] & 0xff;
printf (" \n");
}
として実行させました。
(printf("%02x ", cp[n] & 0xff)だけでは、何故か出力されて来なかったため)
改行は適当に削除しましたが、envlist[0]の中身は以下のようになりました。
00 00 00 01 00 15 b4 50
00 00 00 01 00 26 05 ec
00 00 00 00 00 00 00 00
00 00 00 c7 40 00 00 00
よろしくお願いします。
黒川