アカウント名:
パスワード:
まあ68kでバリバリ非ASCII文字使うことないだろうからまあいいんじゃないっすかね。
strcmp()は2つの機能があって- 文字列の一致不一致の判定- 大小の比較ができるけど、後者にバグがあったってことですね。
バグが出る条件は- m68k- 不一致の文字が非ASCIII文字の場合で、 カーネル内部では大小の比較なんてめったに使わないし、そもそも m68k なんて誰も使ってない。
12年間も誰も気が付かないというか、12年間だれもつかってなかった、ってところでしょうね。
複雑な挙動のテストケース漏れは仕方ないと思うけれど、こんな標準関数レベルですらテストコードが不十分だったんでしょうか。このくらい基本的なテストコードなら、アセンブラでもアーキテクチャ依存でもなく共通で使いまわしができると思うのですが。
元記事を読んでみた。
馬具は、アセンブラじゃなくて、asmを呼び出してるCのコードとの兼ね合い。アセンブラは正しく実装されていて結果を符号付き8-bitで返している。なので、負の値を返すには(カーネル内の問題となったstrcmpの戻り値の型がintだから)符号拡張しなければならんのだが、Cのコードは、このレジスタをcharで受けている。charとだけ書くと、unsigned かsignedか決まっていなくて、処理系ごとにどちらかに決まる。m68kで使っていたコンパイラはsigned扱いだったのね。なので、結果の8-bit目が1だったら、符号拡張されて、負の値がちゃんと返っていた。そこに、コンパイルオプション-funsigned-charを追加したものだから、charはunsigned charと解釈され、char->ssize_tの変換で符号拡張しなくなって、負の値を返さなきゃならないときにも正の値が返るようになってバグが覚醒したと。
見方によっちゃコードのバグではなくビルド設定のミスだな……signed charとして扱う責任をビルド設定に持たすか各コードに持たすか
charの符号有無とかビルド設定切り替えるときは影響範囲確認せぇやって話だな
個人的には符号なしはbyte的な形で扱えば済むからcharは符号付きのが楽な気がしないでもないでもis系関数相手だと符号無しのが楽よな……うーん
このくらい基本的なテストコードなら、アセンブラでもアーキテクチャ依存でもなく共通で使いまわしができると思うのですが。
速度を稼ぐための「(m68k)アーキテクチャ向けに最適化された…アセンブリコード」から、標準のstrcmpを使うように修正した、という話ではないでしょうか。
int strcmp() に対して、明示型キャストなしで char res を return していたのが、to make 'char' be unsigned in the kernel across all architectures(commit 3bc753c06dd0: "kbuild: treat char as always unsigned"). でまずいことに気がつかれた、と読めます。
実装がアセンブリだろうがCだとうが、strcmpをテストするコードはCで汎用的に書けるんだからx86もarmもm68kも同じテストコード使えるでしょ。
であれば、1回まともなテストコードを書いてテストしてたら真っ先に見つけられていたはずでそれすらできてなかったの?ってツッコミでしょ。
後からなら何とでも言えるの典型
標準関数にテストケースが無かったのかなんて、こんな珍事でもなきゃ話題にしようがないだろ
それもあるが、「完全に思い込み」で書いているのが滲み出ている。読解力が無いのか、理解力が無いのか、時間が無いのか、知らんが、少し注意して読めば分かることを見逃している。こういう方は、わかったつもりになって威張り散らす困った人になっていることに気づいてほしい。(昔の自分を見ているようで恥ずかしい。)
#4387590です。自分の書き方が拙くて勘違いさせてしまったようです。私の意図は、#4387690の方の指摘のとおりです。でも、#4387599の方の技術的コメントが頂けたので恥を晒した分以上のリターンはありました。
#馬具という殆ど使わない単語の誤変換はどうして起きたんだろう?
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
私は悩みをリストアップし始めたが、そのあまりの長さにいやけがさし、何も考えないことにした。-- Robert C. Pike
ソート順がおかしくなるってことね (スコア:0)
まあ68kでバリバリ非ASCII文字使うことないだろうからまあいいんじゃないっすかね。
Re: (スコア:2, すばらしい洞察)
strcmp()は2つの機能があって
- 文字列の一致不一致の判定
- 大小の比較
ができるけど、後者にバグがあったってことですね。
バグが出る条件は
- m68k
- 不一致の文字が非ASCIII文字の場合
で、 カーネル内部では大小の比較なんてめったに使わないし、そもそも m68k なんて誰も使ってない。
12年間も誰も気が付かないというか、12年間だれもつかってなかった、ってところでしょうね。
Re:ソート順がおかしくなるってことね (スコア:0)
複雑な挙動のテストケース漏れは仕方ないと思うけれど、こんな標準関数レベルですらテストコードが不十分だったんでしょうか。
このくらい基本的なテストコードなら、アセンブラでもアーキテクチャ依存でもなく共通で使いまわしができると思うのですが。
Re:ソート順がおかしくなるってことね (スコア:5, 参考になる)
元記事を読んでみた。
馬具は、アセンブラじゃなくて、asmを呼び出してるCのコードとの兼ね合い。
アセンブラは正しく実装されていて結果を符号付き8-bitで返している。なので、
負の値を返すには(カーネル内の問題となったstrcmpの戻り値の型がintだから)符号拡張しなければならんのだが、Cのコードは、このレジスタをcharで受けている。
charとだけ書くと、unsigned かsignedか決まっていなくて、処理系ごとにどちらかに決まる。
m68kで使っていたコンパイラはsigned扱いだったのね。なので、結果の8-bit目が1だったら、符号拡張されて、負の値がちゃんと返っていた。
そこに、コンパイルオプション-funsigned-charを追加したものだから、charはunsigned charと解釈され、char->ssize_tの変換で符号拡張しなくなって、負の値を返さなきゃならないときにも正の値が返るようになってバグが覚醒したと。
Re: (スコア:0)
見方によっちゃコードのバグではなくビルド設定のミスだな……
signed charとして扱う責任をビルド設定に持たすか各コードに持たすか
charの符号有無とかビルド設定切り替えるときは影響範囲確認せぇやって話だな
個人的には符号なしはbyte的な形で扱えば済むからcharは符号付きのが楽な気がしないでもない
でもis系関数相手だと符号無しのが楽よな……うーん
Re:ソート順がおかしくなるってことね (スコア:2)
このくらい基本的なテストコードなら、アセンブラでもアーキテクチャ依存でもなく共通で使いまわしができると思うのですが。
速度を稼ぐための「(m68k)アーキテクチャ向けに最適化された…アセンブリコード」から、標準のstrcmpを使うように修正した、という話ではないでしょうか。
int strcmp() に対して、明示型キャストなしで char res を return していたのが、to make 'char' be unsigned in the kernel across all architectures(commit 3bc753c06dd0: "kbuild: treat char as always unsigned"). でまずいことに気がつかれた、と読めます。
Re: (スコア:0)
実装がアセンブリだろうがCだとうが、strcmpをテストするコードはCで汎用的に書けるんだからx86もarmもm68kも同じテストコード使えるでしょ。
であれば、1回まともなテストコードを書いてテストしてたら真っ先に見つけられていたはずで
それすらできてなかったの?ってツッコミでしょ。
Re: (スコア:0)
後からなら何とでも言えるの典型
Re: (スコア:0)
標準関数にテストケースが無かったのかなんて、こんな珍事でもなきゃ話題にしようがないだろ
Re: (スコア:0)
それもあるが、「完全に思い込み」で書いているのが滲み出ている。読解力が無いのか、理解力が無いのか、時間が無いのか、知らんが、少し注意して読めば分かることを見逃している。
こういう方は、わかったつもりになって威張り散らす困った人になっていることに気づいてほしい。(昔の自分を見ているようで恥ずかしい。)
Re: (スコア:0)
#4387590です。
自分の書き方が拙くて勘違いさせてしまったようです。私の意図は、#4387690の方の指摘のとおりです。
でも、#4387599の方の技術的コメントが頂けたので恥を晒した分以上のリターンはありました。
#馬具という殆ど使わない単語の誤変換はどうして起きたんだろう?