トップページtech
51コメント18KB

Bus Error って?

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
BusErrorって何ですか?

0002 NGNG
ブスに遭遇したとき出ます
0003デフォルトの名無しさんNGNG
バスエラー:
ワード単位のアドレッシングモードで
奇数番地にアクセスしようとした場合など
CPUのマニュアルを参照。
セグメンテーションフォルト:
書きこみ禁止のエリアに書きこみにいった場合や
そのタスクで確保していないアドレスへアクセス
しようとした場合など。
OSの資料を参照。
補足方法:
純粋にバグだから出ないようしてリリース
するのが基本。
Windowsなら構造化例外処理で補足できる。
デバッガーやエミュの開発以外では補足する
必要なし。
0004デフォルトの名無しさんNGNG
今まで見たことないからなんとも言えんが、
”ワード単位のアドレッシングモードで
奇数番地にアクセスしようとした場合”

って、そんなん分からんやろ〜
0005デフォルトの名無しさんNGNG
X68000でよくだしたなぁ〜
0006デフォルトの名無しさんNGNG
>>4
検出について言ってるのなら、
CPUのA0というピンの電圧がHIになってるかどうか
だけの問題。ハード的な信号レベルの処理なんで。
0007デフォルトの名無しさんNGNG
>>6
A0って?
アドレスバスの最下位bitみたいな物?
0008通りすがりNGNG
>>6
ってことは、どうやってデバッグするんだ?
0009デフォルトの名無しさんNGNG
>>4
普通、バスエラーを検出するプロセッサは「バスエラー例外」てのを
備えていて、スタックを辿ると問題の発生したプログラムアドレスと
原因となるメモリアクセスがわかるようになってる。
0010デフォルトの名無しさんNGNG
>>8
普通のGPFと同じように、不正なメモリアクセスでおきている
んだから、ポインタ関係のコードを直せばOK。
4の意味がわからないようなら、たとえば一般に malloc は偶数
アドレスを返すインプリメントが多いので

char* p = (char*) malloc(100);
int* q = (int*) (p+1);
*q = 0;

などがエラーになる。
0011通りすがりNGNG
>>10
なんでエラーになるんだ??
p は 100バイトのメモリーを確保してるはず。
それでもって、q はたかが int のポインタ。

で、*q は4バイト。

情けないが分からん・・・・・・
0012デフォルトの名無しさんNGNG
だから、CPUによっては奇数番地からのワード(16ビットのint とか、
short) のアクセスは違反になるんだってば。あと 4byte アライン
じゃない 32bit 値のアクセス、とかも。

C や C++ でも、ポインタ値をほかの型のポインタ値にキャストした
あとの、そのポインタの正当性については保障していない。つまり、
これが実行時エラーとなるからといって、そのCPUでは C / C++ が
ちゃんと動いていない、ということではない。

CPU と OS によっては、この例外を OS がキャッチして、それなり
に動くようにしてくれることもある (ALPHA/AXP マシンなど) が、
その場合実行時間が大変なことになるので、数値計算などでそんな
プログラムを書くとアホ扱いされる。
001312NGNG
x86 (IA32?) 系の CPU はこのへん気にしなくてもよかったと思う。
Palm の Dragon Ball はどうなの?>識者
0014デフォルトの名無しさんNGNG
>>11
バスエラーてのは、「ワード境界をまたぐメモリアクセスがワンアクションでできないハードウェア」が
持っている機能なんだ。
ソフト的には何ら間違いが無くても、ハードウェアにその機能がない。
それを教えるために存在する例外なんだな。バスエラーは。
>>10の例だと、qは奇数になるが、奇数アドレスに対して16/32ビット単位でのアクセスをしようとする
も、ハードウェアにその機能がないので例外が出ると。そういうこと。
0015デフォルトの名無しさんNGNG
>>11
たとえばモトローラ系プロセッサは
奇数アドレスからのワードアクセスを禁止しているから
10の例だとpが奇数になってるからエラーになりますんですよね?
0016通りすがりNGNG
どうもすんません。

仕組みの方は全然わからないけど、理由は分かった!
今までみたことがないってことは、運が良かっただけか・・・
0017デフォルトの名無しさんNGNG
>> 13
DragonBall == 68000 なのでバスエラ〜
10 のコード実際やってみたら、やっぱりバスエラ〜
0018デフォルトの名無しさんNGNG
>仕組みの方は全然わからないけど、理由は分かった!
>今までみたことがないってことは、運が良かっただけか・・・

10のようなおかしなポインタ操作や、構造体のメンバをオフセットで
参照するような真似をしなければ普通はでません。
0019デフォルトの名無しさんNGNG
いや、>>10はただのサンプルで、

        char* p;
        int a, n;
        (中略)
        a = *((int*)(p+n)); // a = *((int*)&p[n]) でも可。

みたいな、一見ごく当たり前のポインタ操作でもnが奇数だったら起きるわけよ。
0020>>18NGNG
インテルのチップしか使ったことなけりゃ見たことあるはずないし。
0021名無さんNGNG
>インテルのチップしか使ったことなけりゃ見たことあるはずないし
386以上なら出せるよ。出るようになってれば。
UNIXWAREなら出たはず。Windowsもでるんでないのかな。
バスエラーって表示でないだけで。
0022紅衛兵NGNG
例外0Eとは違うの? よくわからん。
0023デフォルトの名無しさんNGNG
>>21
そなの?そりゃしらんかった。どうすると出るわけ?
0024デフォルトの名無さんNGNG
セグメント記述子のどっかのフィールドじゃなかった?
どこかのフラグがオンだとハードが境界跨った
アクセスでバスエラー出すことになってるらしい。
つまりOSがプロセス起動するときにフラグ立ててればってこと。

0025デフォルトの名無しさんNGNG
x86の場合は、アライメント・チェック・フォルトってやつですね。
CR0のビット18が1で、
EFLAGSのビット18が1の場合、
特権レベル3(ユーザーモード)で動いているプログラムに限って
アライメントが合っていないアクセスを行うと割り込みが発生する。
Windowsの場合、CR0のビット18は多分0になっているので、
この機能は使えないと思う。
0026デフォルトの名無しさんNGNG
バスエラーとアドレスエラーを取り違えていないか?

バスエラーってCPUからのバス操作に対してバスから応答がないとき
ようするにメモリやI/Oの無いところにアクセスしたときじゃねぇの?

アドレスエラーは奇数アドレスからのワードアクセス
とはいえ、68020以降はデータは可コードは不可なので
データアクセスでは発生しないのよ。
0027デフォルトの名無しさんNGNG
>>26
それはSegmentaition Faultだったはず
0028デフォルトの名無しさんNGNG
Windowsは構造化例外で定義されてる。
実際に処理が実装されているかどうかは不明。

>EXCEPTION_DATATYPE_MISALIGNMENT
>境界合わせをサポートしていないハードウェア上に存在する、
>境界合わせされていないデータに対して、 スレッドが読み取りや
>書き込みをしようとしました。たとえば、 16ビット値は
>2バイト境界に、 32ビット値は4バイト境界に、
>それぞれ境界合わせされてなければなりません。
002926NGNG
x86の話しと680x0の話しがまざっているような。
26の話しは680x0の話しね。

>>27
Segmentation Faultって論理アドレスの話しで
論理アドレスとして割り当てのないアドレス(セグメント)にアクセスした場合。

Bus errorというのは物理アドレスの話しで、ハード的に割り当てのない
(BUSからの応答がない)アドレスにアクセスした場合。

Address errorというのは奇数アドレスにワードアクセスした場合。
68000ではデータとコード両方とも違反。68020以降(10っだたかもしれない)
は奇数アドレスのワードデータアクセス可。コードは違反。

>>28
WinNTはx86だけではなくAlpha chipやMIPS(もうサポートされていない)と
あと何だった可忘れたチップセット用のものもある。
だからAPIのインタフェースとしてはx86以外の場合も考慮されている。
しかしEXCEPTION_DATATYPE_MISALIGNMENTはx86では発生しない。
003027の名無さんNGNG
http://www2s.biglobe.ne.jp/~hig/q_a/Programing_QA02.html#Q14
>メモリーから 4 バイトの大きさのデータを読み込もうとすると、4 で割り切れるバイトアドレス (メ
>モリー上の番地) からしか読み込めない。そのような制限があるとき、4 で割り切れないアドレスを
>指定してメモリーを読みにいくとバスエラーが起きる。
0031デフォルトの名無しさんNGNG
真のプログラマーならアラインメンとは意識すべきでしょう。
x86 はアラインメントずれててもエラーにはならないけど
メモリアクセスが2回に分かれてしまうので処理が遅くなる。

このページからのウケウリなり
http://www.csl.sony.co.jp/person/fnami/asm.htm

アラインメントずらして得なことって何かある?

0032デフォルトの名無しさんNGNG
得なことはないですが、ずれるプログラムを書く奴はいます。
003326NGNG
>>30
偽情報を流しているページの紹介ありがとう。
それを信じる厨房宣言ありがとう。
0034厨房NGNG
int main() {
int v = 0x1234;
char *p = (char *)&v;
printf("%d\n", look(&(p[1])));
printf("%d\n", look((int *)0x80000000)); /* SEGV */
printf("%d\n", look((int *)0)); /* SEGV */
}

int look(int *p) {
return *p;
}

X86のlinuxでは出ない。
0035デフォルトの名無しさんNGNG
>>33
んとさぁ、エラーの名称や意味なんて、CPUやOSによって様々なんだよ。
68000系の名称がCPU全体の常識だと思ってるなんて恥ずいよ。
0036デフォルトの名無しさんNGNG
26=29=33は680x0と断っているように見えるが
0037デフォルトの名無しさんNGNG
>>35-36
26は>>30を「偽情報を流しているページ」と評した。
そのページは、68000系のCPUに特化したページではないので、
そのページの記述内容に沿って、「偽情報」かどうかを
判断しないといけない。

俺には、それを判断できるだけの知識は無い。

26もあのページを「偽情報」と言い切るのだったら、どこが「偽」なのか
解説して欲しい。
0038デフォルトの名無しさんNGNG
もういいよ厨房どうしの煽り合いで上げるなよ。
0039デフォルトの名無しさんNGNG
>>37はまともかと。
0040デフォルトの名無しさんNGNG
>>31
MMXやSSE等のSIMD命令では、メモリアクセスでアラインメントをずらしたくなる。
扱っているデータは8,16,32ビットのデータ列なのに、
64,128ビットのアラインメントに合わせてメモリアクセスするのはちょっと酷。
SIMDの場合でもアラインメントを合わせないと、遅くなるよね?
0041デフォルトの名無しさんNGNG
データアライメントは気にする必要あるかも
でもいまどきコードアライメントを気にする必要ってあるの?

Pentiumなどのバーストリードでコードをキャッシュにほうり込むプロセッサだと
コードアライメントが悪くてもあまり変わりないような気もする。
0042デフォルトの名無しさんNGNG
むー、俺も26にどこが偽情報なのか解説して欲しい。

俺はあのページの内容で正解だと思ってた。
0043デフォルトの名無しさんNGNG
http://e-www.motorola.com/brdata/PDFDB/MICROPROCESSORS/32_BIT/68K-COLDFIRE/M680X0/MC68000UM.pdf
よっぽど確かなソース♪
0044デフォルトの名無しさんNGNG
>>41キャッシュ=レジスタならそうだろうけどな
0045デフォルトの名無しさんNGNG
>>44
はあ?意味不明。
004644NGNG
「キャッシュメモリ=レジスタなアーキテクチャだったら
>>41 の言ってることも正しいだろうけど
そんなCPUきいた事ない。」
という意味で言った。
キャッシュメモリとは言え1回のアクセスですむところを2回
アクセスするのはやっぱり無駄があるよ。
0047デフォルトの名無しさんNGNG
コードアライメントの話しじゃないの?

キャッシュメモリ=レジスタなアーキテクチャなんてことの前に
レジスタってデータだよね。

レジスタにコード置いて動けるプロセッサなんて聞いたこと無い。
0048デフォルトの名無しさんNGNG
#pragma pack( push, tStruct, 1 )

#pragma pack( pop, tStruct, 1 )
0049デフォルトの名無しさんNGNG
名作。
以降は全てクソ
0050デフォルトの名無しさんNGNG
けっきょく43のリンク先で決着したの?
0051デフォルトの名無しさんNGNG
メーカのマニュアルを持ち出されては返す言葉もございません。
わたしがまちがっていました。首くくって死にます。
■ このスレッドは過去ログ倉庫に格納されています