[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:01032] Re: 64bit Solaris(SPARC)環境下でのSiganl-11エラー



お世話になっております、黒川です。

>> > >> 	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  

よろしくお願いします。

黒川