FreeBSDを語れ Part38
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2014/07/14(月) 05:03:19.63The FreeBSD Project
http://www.freebsd.org/ja/
前スレ
FreeBSDを語れ Part37
http://peace.2ch.net/test/read.cgi/unix/1390323139/
関連スレ
初心者もOK! FreeBSD質問スレッド その118
http://peace.2ch.net/test/read.cgi/unix/1397057895/
010480
2014/07/30(水) 13:18:52.10作ったソフトに関係なく、 4KB を越える EPS を貼ると、必ずフリーズする事がわかりました。
4KB 未満の EPS ならフリーズしません。また、4KB を越えても jpeg と png はフリーズしませんでした。
>>96
原因は送った先にあると言うことでしょうか?
FreeBSD の ghostscript9 が win や linux のと違う振る舞いをする、とかですか?
0105名無しさん@お腹いっぱい。
2014/07/30(水) 13:19:11.62http://www.freebsd.org/doc/ja/books/handbook/x11-wm.html
とか
0106名無しさん@お腹いっぱい。
2014/07/30(水) 13:22:50.59サイズを4KBの倍数になるようパディングしたら正常に動作したりして
010784
2014/07/30(水) 14:25:05.34力技を使えばできるよ。
まず、インストール用に配布されてるISOイメージの中で一番でっかいのをDVD-RAMに焼く。
こいつには(ちょっと古いしい色々足りないけど)Xとかある程度のpkgが含まれていて、
bsdconfigにもちゃんとCD/DVDからインストールするメニューがある。
もっともネット未接続だとpkg bootstrapがWebを観にいって失敗するんだが...
実はDVD上にも(ちょっと古いけど)pkgをtxz化したファイルが存在するので、
/etc/pkg/FreeBSD.confを書き換えてローカルファイルを読み込むように設定した上で、
名前も変更してファイル置いとけば、
pkg bootstrapも成功してDVD内の全pkgをインストールできるようになるよ。
正直オススメはしないが。
0108名無しさん@お腹いっぱい。
2014/07/30(水) 19:31:52.29以下想像:
パイプかなんかで送っててパイプのバッファサイズが4KBしかない。
そこにwrite一発でファイル全体を送ってしまって、
書けた量を確認せず、waitでそのパイプ先の終了を待っている。
パイプ先は次の4KBが来るのを待っている。
0109104
2014/07/30(水) 20:56:02.85その場合、直すべきは一発でファイル全体を送っているところでしょうか?
LibreOffice の source にバグがある?
0110名無しさん@お腹いっぱい。
2014/07/30(水) 20:57:06.72関連しそうなとこは
filter/source/graphicfilter/ieps/ieps.cxx の RenderAsBMPThroughGS() で、
gsのコマンドライン作って、RenderAsBMPThroughHelper() を呼んで、
中で runProcessWithPathSearch() でプロセス作って、
osl_writeFile() で pBuf 内のデータを nBytesRead バイトだけ書き込んでる。
sal/osl/unx/file.cxx 内の osl_writeFile() は書けたバイト数を管理してるように読める。
なので、デバッガかデバッグプリントつっこんで、
nBytesRead が正しいファイルサイズになってるかどうか調べてみたらいいんじゃないかな。
で、これが 4096 とかになってたら、その原因を探っていけばいい。
EPSを読むところがおかしいという可能性がある。
俺は今自由に動かせる 10-R がないので、これ以上は無理。
0111名無しさん@お腹いっぱい。
2014/07/30(水) 21:19:56.870112104
2014/07/31(木) 02:13:19.12わかりました。その辺り調べてみます。
ようやく原因が絞れて希望が出てきました。
>俺は今自由に動かせる 10-R がないので、これ以上は無理。
ちなみに、私の今のテスト環境は 9.3R です。
LibreOffice 4.2.5.2 がフリーズするのは 10.0R も 9.3R も同じでした。
0113名無しさん@お腹いっぱい。
2014/07/31(木) 10:11:29.46面白そうなんで自分も見てみた。
RenderAsBMPThroughHelper()って、これダメじゃないか?
osl_writeFile()に渡してる引数&nCountでwrite()で書けたバイト数を貰ってくるが、
パイプから読むのは
if (nCount == nBytesRead)
の場合だけじゃん。
nCount != nBytesReadのときは子プロセスの出力読まずに終了待ちしようとするみたいだし。
0114104
2014/07/31(木) 11:31:27.04>面白そうなんで自分も見てみた。
ありがとうございます。自分はC言語が得意ではないので助かります。
>RenderAsBMPThroughHelper()って、これダメじゃないか?
>osl_writeFile()に渡してる引数&nCountでwrite()で書けたバイト数を貰ってくるが、
>パイプから読むのは
>if (nCount == nBytesRead)
>の場合だけじゃん。
>nCount != nBytesReadのときは子プロセスの出力読まずに終了待ちしようとするみたいだし。
この問題で、4KB未満のEPSファイルではフリーズせず、
4KBを越えるとフリーズするのが説明できるでしょうか?
また、修正案はあるでしょうか?
いただければ、反映させて LibreOffice を make して試してみます。
0115名無しさん@お腹いっぱい。
2014/07/31(木) 11:32:55.41Ubuntuと同じって言っても...
GTK+3系のにしたいのなら、PC-BSDにでもしたら?
FreeBSDをPC-BSDにする方法は以下のURL
http://wiki.pcbsd.org/index.php/Turn_FreeBSD_into_PC-BSD%C2%AE
0116名無しさん@お腹いっぱい。
2014/07/31(木) 12:02:21.000117名無しさん@お腹いっぱい。
2014/07/31(木) 12:19:55.30> 修正案はあるでしょうか?
丸投げしすぎ。
どの言語であれ、ブレークポイント掛けてデバッガでトレースしていくか、
printfなりなんなりをつっこんで、ちまちまデバッグしていくのが、発見者の努め。
言語による差異なんてほとんどない。
0118名無しさん@お腹いっぱい。
2014/07/31(木) 12:21:34.53って、自分では何やったんだよ。
0119名無しさん@お腹いっぱい。
2014/07/31(木) 12:52:06.14違う。俺が書いたURLを見てみな。
FreeBSDをインストールしたあとに、PC-BSDやTrueOSにするには、どうしたら良いのかが書いてある。
別にzfsにする必要はない。
0120名無しさん@お腹いっぱい。
2014/07/31(木) 13:21:55.34Ubuntuは無理なのでGnome shellになると思いますが
まっさらな状態からなので、PC-BSDにしたいのならPC-BSD入れます
FreeBSD2.1から使ってる頭から見るとPC-BSDはかなり違うので
出来ればFreeBSDにUnityみたいなインターフェイスを入れたいと思ったのですが…
もしかして、これを入れればいいのかな
/usr/ports/x11/gnome-shell
これだけだと、ビジュアルシェルだけしか入らないような
0121名無しさん@お腹いっぱい。
2014/07/31(木) 13:49:51.00自分も1.1時代から遊んでいますよ。
PC-BSDも10系になってからports,pkgを積極的に使うようになっています。
ですから、さほど違和感があるってほどじゃないと思いますよ。
Unityは無理ですが、Gnome3やCinnamonならPC-BSDのports treeを持ってきてbuildしたり、先に示したリンク中にあるpkgのreposなどを追加してpkg installで入れるという方法もあります。
pcdmはqt4関連を入れてから、gitでソースを持ってきてbuildしてあげればOKです。
まっさらなら、FreeBSDのportsとPC-BSDのportsとバージョンがバッティングしないはずなので、それでやってみるのはどうでしょう?
0122名無しさん@お腹いっぱい。
2014/07/31(木) 14:01:06.11PC-BSDでports, pkgが使えるのですか
それならまずPC-BSDをやってみようかな
0123名無しさん@お腹いっぱい。
2014/07/31(木) 15:10:19.62お節介ついでなのですが、PC-BSDのISOを落としてきてインストールすると、
/usr/local/pkg/repos/pcbsd.conf
のURLのバージョン部分が10-STABLEになっているんじゃないかと思います。
なんかフォルダ名を変えたみたいで、url=の部分を以下のように書き換えると
pkgが正常に動作するようになると思います。
url: "http://pkg.cdn.pcbsd.org/10.0-STABLEJULY2014/amd64"
あとPCDMはgitじゃなくてsvnでしたね...
0124名無しさん@お腹いっぱい。
2014/07/31(木) 18:06:09.96> また、修正案はあるでしょうか?
> いただければ、反映させて LibreOffice を make して試してみます。
と言うけど、Libre環境は仕事で必要なんじゃなかったっけ?
自分で修正してフリーズは回避できても、そういう場合
得てして潜在的に他にもおかしな処理があるかも知れない。
それが目に見えて分かるフリーズとかではなく、情報(計算数値など)
が微妙に間違って表示されるようなものだったとしたら、
仕事になんか安心して使えない。
0125名無しさん@お腹いっぱい。
2014/07/31(木) 19:19:49.7420055 a.out GIO fd 1 wrote 4096 bytes
...
20055 a.out RET write 1048576/0x100000
ってなる。write() の書けたバイト数は、RET の行を見ないといけないな。
wrote 4096 bytes は、その分だけ表示してるってだけの意味に考えた方がいい。
というわけで、振り出しに戻る。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int nBytesWritten;
char *p = malloc(1024*1024);
memset(p, 'x', 1024*1024);
nBytesWritten = write(1, p, 1024*1024);
fprintf(stderr, "%d bytes\n", nBytesWritten);
return 0;
}
0126名無しさん@お腹いっぱい。
2014/07/31(木) 19:44:24.69パイプサイズ自体は4096byteのはずだけど、syscall内部でうまく計らってるのか??
0127名無しさん@お腹いっぱい。
2014/07/31(木) 19:52:42.01それはFreeBSDも同じ。問題はパイプの read() だろ。
0128名無しさん@お腹いっぱい。
2014/07/31(木) 20:09:51.92ちょっと前が 64kB
もっと前が 4kB
0129名無しさん@お腹いっぱい。
2014/07/31(木) 20:16:46.90生のktrace.outが欲しいわ。
タイムスタンプとかスレッドIDとか入ってるやつ。
でないと、CALLとRETの対応がつかなくて困る。
0130名無しさん@お腹いっぱい。
2014/07/31(木) 20:25:53.08http://www.atmarkit.co.jp/ait/articles/1209/07/news125.html
> 例えばFreeBSD 10-CURRENTでは、パイプで使われるページ可能な
> カーネルメモリを使ったパイプのバッファサイズは、4KBから64KB
> の間で可変になっている。
> write(2)でどれだけ一気に書きこんでも、read(2)で読み込まれる
> サイズの上限が64KBに制限されている
0131名無しさん@お腹いっぱい。
2014/07/31(木) 22:11:49.30LibreOfficeですらこんな糞コーディングしちゃってることのがショックだ。
0132名無しさん@お腹いっぱい。
2014/07/31(木) 22:12:41.660133名無しさん@お腹いっぱい。
2014/07/31(木) 22:33:18.300134名無しさん@お腹いっぱい。
2014/07/31(木) 22:47:06.92ttp://docs.libreoffice.org/filter/html/ieps_8cxx_source.html#l00285
これか。
306行目でパイプ閉じてるから、向こうも書けなくなって落ちるのを期待してるのかもしれん。
落ちてくれない相手だと終了待ちで止まることになるかもしれんが……この可能性は低い、かな。
で、これだと書き込み中に相手プログラムがパイプに応答返してきた場合は、
受け取りしないからパイプバッファが足りなくなってエラーまたはデッドロックだな。
osl_writeFileとかのパイプバッファ溢れの挙動がよく分からんけど、
この周辺にprintfデバッグ仕込んで走らせれば何が起きてるかは分かるね。
あとosl_writeFileのソースが見つからないけど、この中で分割書き込みしてあるかどうかかな…
>>125
write単発4KBで止まってるならその周辺って事で戻ってねぇと思うけど
>>131
OOoからの派生だが、OOoのコード(安定性含む)って評判良かったか?
マシなコードにするって目標が合っても、それが追いつくかどうかは別の話だと思う。
0135名無しさん@お腹いっぱい。
2014/07/31(木) 23:31:24.37>write単発4KBで止まってるならその周辺って事で戻ってねぇと思うけど
すまんが何言いたいのかわからん
0136104
2014/08/01(金) 00:18:08.90遅くなりました。ktrace.out アップロードしました。
新しく取り直したものです。3MB あります。
http://fast-uploader.com/file/6962374997550/
0137104
2014/08/01(金) 00:28:41.66私が確認したのは amd64 だけです。
前スレに同じ様にフリーズする人が何人かいたのですが、どちらか聞き損ねました。
フリーズを起こすのは簡単です。
10R か 9.3R に LibreOffice 4.2.5-2 を入れて、
4KB を越える EPS ファイルを impress で挿入するだけです。
ダイヤログで「開く」を押した瞬間にフリーズします。
preview が on になっていると、選択しただけでフリーズします。
0138104
2014/08/01(金) 00:36:27.07常用している PC には 9.1R + LO 3.5.6.2 を残してあります。
9.3R や 10.0R を入れて試しているのは予備機の1つです。
LO4 が安心して使えないのは同意です。
でも、9.3R にも 10R にも LO4 しかないのです。
0140名無しさん@お腹いっぱい。
2014/08/01(金) 05:52:13.29今どきcommit前にレビューのないプロジェクトって……
0141名無しさん@お腹いっぱい。
2014/08/01(金) 06:27:09.350142名無しさん@お腹いっぱい。
2014/08/01(金) 10:53:05.62それで256Kになったんですね
わかります。w
0143104
2014/08/01(金) 11:42:06.13私がもう少し大きな EPS でテストして貰ってたら、同じ様にフリーズしてたのか。。。
win でどうか、大きな EPS を作って試して見ます。
0144名無しさん@お腹いっぱい。
2014/08/01(金) 11:48:24.21とりあえず現時点まとめ。
1120 100087 soffice.bin 1406819284.268085 CALL write(0x31,0x815414000,0x4797)
1120 100281 soffice.bin 1406819292.199891 PSIG SIGTERM caught handler=0x80083
0b90 mask=0x0 code=0x10001
1120 100087 soffice.bin 1406819292.200801 GIO fd 49 wrote 4096 bytes
1120 100087 soffice.bin 1406819292.200812 RET write 18327/0x4797
という流れなんで、スレッド10087がwrite()を呼んだあと、
SIGTERMが来るまでそれが終わっていないことがわかる。
SIGTERMで受け取り側が刺激されて完了するか死ぬことで、write()が完了している。
とりあえずwrite()を完了させるために、gsに細工してみてくれないか?
/usr/local/bin/gs は gsc へのリンクになっていると思うけど、
これを
#!/bin/sh
cat >/tmp/gs$$
gsc "$@" </tmp/gs$$
rm -f /tmp/gs$$
というシェルスクリプトに変更して試してみてくれ。
0145名無しさん@お腹いっぱい。
2014/08/01(金) 12:12:40.57selectなりしながらread/writeするのがありがちなのかな。
スレッド作っちまえって話もあるか。
0146104
2014/08/01(金) 12:17:18.50変えてみました。結果、フリーズなくなりました!
それどころか、正常に画像が表示されました。不思議です。
source を見ると、RenderAsBMPThroughGS() と RenderAsBMPThroughConvert()
のどちらかを実行するようになっているので、Convert の方が実行されたのでしょうか?
とにかく、大きな前進です。
0147名無しさん@お腹いっぱい。
2014/08/01(金) 12:21:45.14gsからのバッファがあふれて入力を止めてしまうってことがあるだろうか。
内部でレンダリングが完了しないと、BMPの出力なんて始められないと思うんだけど。
まあでも、そういう可能性も考慮してLO作れって話ではある。
0148名無しさん@お腹いっぱい。
2014/08/01(金) 12:53:12.30> source を見ると、RenderAsBMPThroughGS() と RenderAsBMPThroughConvert()
> のどちらかを実行するようになっているので、Convert の方が実行されたのでしょうか?
なんでそうなんだよ
0150名無しさん@お腹いっぱい。
2014/08/01(金) 13:03:16.65PostScriptインタプリタは普通に作れば、入力が全部来てから処理を始めるなんていう
間抜けな構成にはならない。
届いたところまで評価して出力する構成になるのが普通。
0151名無しさん@お腹いっぱい。
2014/08/01(金) 13:20:10.05そうなの?
最後まで各ピクセル値が確定しないように思うんだけど。
最後の最後に、あ、この線も追加で引いてなんてコード書けるでしょ。
0152名無しさん@お腹いっぱい。
2014/08/01(金) 15:53:31.50VirtualBoxに10.0入れてやってみたら、図が表示されないけど、フリーズしない。
9.2を9.3に上げてLOもGSも入れ直してみたら、フリーズしない。
どっちも64ビット。
0153名無しさん@お腹いっぱい。
2014/08/01(金) 15:55:52.00ぐっじょぶ!
>>150
詰まったパイプが出力段か入力段が分からんとなんとも言えん気もするが…
処理は開始できるけど、出力の頭辺りが確定しないと出力を始められないよ。
>>151
PSだとshowpageとかでページ確定してしまえばそのページは出力できるけど、EPSではどうなるやら
0154名無しさん@お腹いっぱい。
2014/08/01(金) 16:39:30.46#!/bin/sh
(cat; echo done >&2) | gs -q -dBATCH -dNOPAUSE -dPARANOIDSAFER -dEPSCrop -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r300x300 -sDEVICE=bmp256 -sOutputFile=- - | (sleep 10; cat)
./lotest.sh < sinxplot.eps > sinxplot.bmp
って実行したら、すぐに done って表示される。10秒待って BMP が生成される。
つまりパイプへの出力バッファが埋まったから入力が中断されてるってわけではない。
でも、もしかすると、フリーズする環境ではこれはどうなるんだろう。
>>104 試してみて。gs は>>144の修正する前の gsc へのリンクね。
0155名無しさん@お腹いっぱい。
2014/08/01(金) 16:40:39.410156名無しさん@お腹いっぱい。
2014/08/01(金) 16:41:49.200157名無しさん@お腹いっぱい。
2014/08/01(金) 16:46:18.210158104
2014/08/01(金) 16:56:01.15もとの gs に戻して、LO がフリーズする様に戻してから、やってみました。
./lotest.sh: 2: Syntax error: Bad fd number
と表示され、10秒後に終わって、bmp 1.5MB ができました。
できた bmp を表示してみると、サイズが大きくなっている以外は正常でした。
0159名無しさん@お腹いっぱい。
2014/08/01(金) 16:57:46.14>>156
0160104
2014/08/01(金) 16:58:45.27ghostscript9-9.06_7
Name : ghostscript9
Version : 9.06_7
0162名無しさん@お腹いっぱい。
2014/08/01(金) 18:05:13.38シェルを介する何処かでパイプの挙動が違うのかな。
catが組み込みで動いたりパイプに対する対処がされてたり…
0163名無しさん@お腹いっぱい。
2014/08/01(金) 19:17:20.64フリーズする環境とバグ探し能力の両方を持った人、協力よろ。
0164名無しさん@お腹いっぱい。
2014/08/01(金) 22:00:10.59なるほど。
たしかにLOでepsを開くとそのオプションでgs(gsc)が呼び出されてるわけですね。
私のところはフリーズする環境ですが、シェルスクリプトとして起動すると性状にbmpが作成されて、LOからだとgscのプロセスが残ったままになります。
このgscをkillすると読み込んだepsがLOで表示されるんですよね。
0165104
2014/08/01(金) 23:14:28.26どうも、フリーズする環境としない環境があるみたいなので。
0166104
2014/08/01(金) 23:27:22.780167164
2014/08/02(土) 11:18:55.68私のところはamd64の10-stable p5です。
LibreOfficeは、この話が出てきてからcvsでとってきたportsで入れました。
プラットフォームはESXi 5.5です。
0168104
2014/08/02(土) 11:31:00.15了解です。私の 9.3R amd64 pkg とは amd64 だけ共通ですね。
shell は何でしょうか? 私は tcsh です。
0169名無しさん@お腹いっぱい。
2014/08/02(土) 11:34:26.730170164
2014/08/02(土) 11:37:41.82ログインシェルはtcshにしています
0171名無しさん@お腹いっぱい。
2014/08/02(土) 12:03:15.56いざ FreeBSD の pkg を見てみると mono や monodevelop 等の環境が充実していることに驚いた。
0172名無しさん@お腹いっぱい。
2014/08/02(土) 16:23:26.660173名無しさん@お腹いっぱい。
2014/08/02(土) 16:35:29.210174104
2014/08/02(土) 17:04:28.53二人とも tcsh ですね... これが関係しているのですかね?
>>162 さんが shell に触れているので気になりました。
0175名無しさん@お腹いっぱい。
2014/08/02(土) 17:34:26.310176名無しさん@お腹いっぱい。
2014/08/02(土) 18:10:26.08へえ、最近はそんなにでかいんだ
0177162
2014/08/02(土) 18:20:02.16シェルスクリプト介さずプロセス作った時のトラブルに影響するのかな?
>>175
#!/bin/shが実際どんなシェルにリンクしてるかは一応環境依存だけど、
そもそもエラー再現するときがgsc直で呼んでる時だからやっぱ関係ない系
0178名無しさん@お腹いっぱい。
2014/08/03(日) 09:01:53.51sal/osl/unx/process.cxx
の中の
osl_executeProcess_WithRedirectedIO の処理を修正すれば良いんでしょうかね。
ちょっと追っかけてみます。
0179名無しさん@お腹いっぱい。
2014/08/04(月) 02:46:56.10http://code.woboq.org/libreoffice/libreoffice/sal/osl/unx/process.cxx.html#461
最終的には osl_psz_executeProcess の中の osl_waitCondition とかに行くのですかね...
複雑過ぎです...
0180名無しさん@お腹いっぱい。
2014/08/04(月) 21:24:21.44再現性について進展。
pstoeditがインストールされていると、
RenderAsEMF()が成功するのでRenderAsBMP()を呼ばず、フリーズしない。
pstoeditがインストールされていないと、フリーズする。
0181名無しさん@お腹いっぱい。
2014/08/05(火) 11:49:53.00マスターのPORTVERSIONが上がったとき、そのバンプを元に戻すのは
やっぱ忘れやすいよなw
0182名無しさん@お腹いっぱい。
2014/08/05(火) 12:14:30.80お疲れさまです。
なるほど。FreeBSDでもフリーズする人しない人が居る理由が判りました。
判ってよかったです。
0183名無しさん@お腹いっぱい。
2014/08/05(火) 16:36:43.00RenderAsEMF も osl_executeProcess_WithRedirectedIO を使っているんですね。
このときは FreeBSD でも問題ないのは、gsc の問題を意味するのでしょうか?
>>164 にもあるようにフリーズ中は gsc が残っていて、これを kill するとフリーズは解けるのですが、
画像が正しく表示はされる事はないです。例えば、外枠だけ表示されて中が真っ黒となります。
gsc の処理が途中で止まっている様に見えます。
0184名無しさん@お腹いっぱい。
2014/08/05(火) 18:16:19.76>このときは FreeBSD でも問題ないのは、gsc の問題を意味するのでしょうか?
いいえ。pstoeditの出力は標準出力ではなく指定したファイルに行うようになっているので該当しません。
どうせ読むならもっと正確にコードを読んで判断してください。
0185名無しさん@お腹いっぱい。
2014/08/05(火) 19:03:53.23pstoedit入れずにLinuxで巨大EPSのテストもな。1MBはいるな。
0186143
2014/08/05(火) 19:50:25.25分かりました。
>>185
linux は手元にないです。Window はテストしました。
440KB の EPS で正常に動作しました。
0187名無しさん@お腹いっぱい。
2014/08/05(火) 22:24:50.35ここでやるのはもうだいぶスレ違い。
0188名無しさん@お腹いっぱい。
2014/08/05(火) 22:31:23.20言われて終わる可能性は高いからなあ。スレ違いとまでは言えないと思うが。
SolarisとかでLibreOffice動くんだろうか。わざわざ試す気にはなれないけど。
0189名無しさん@お腹いっぱい。
2014/08/06(水) 02:12:13.470190名無しさん@お腹いっぱい。
2014/08/06(水) 05:59:35.22ではFreeBSDのパイプの実装を直すべきって言うかね?
0191名無しさん@お腹いっぱい。
2014/08/06(水) 08:05:06.58入れるか。
どっちにしろ「FreeBSDの話題」だよね?
0192104
2014/08/06(水) 11:17:26.57>pkgngって欠陥品では・・・
pkgng はまぁ良いとしても、デフォルトで latest なのがマズイと思う。
latest はローリングリリースで数が減ったりするから、タイミングによって欲しいモノがない。
デフォルトはタグの付いたリポにしとくべきだ。
最低でも、そう変更する方法の説明があるべきだけど、それもない。
0193名無しさん@お腹いっぱい。
2014/08/06(水) 13:22:33.96>本当に実装がまずいならそうするべきだし、あるいはportsにFreeBSD専用のパッチを
>入れるか。
ばーか。お前は今までの話を理解してないんだな。
0194名無しさん@お腹いっぱい。
2014/08/06(水) 13:31:10.23もう一度問題の原因を読んで考えなおせ
0195名無しさん@お腹いっぱい。
2014/08/06(水) 14:58:18.550196191
2014/08/06(水) 15:45:43.49すまない、確かに自分がわかっていなかったようだ。
「gsに対するパイプへのreadをちゃんとせずにwriteするからお互いにwriteしようと
してデッドロックする」ということであっているだろうか。
これに対する修正なら確かにFreeBSD固有ではないな。ツッコミ感謝。
0197名無しさん@お腹いっぱい。
2014/08/06(水) 15:50:41.55パイプからの1回のreadで全サイズ読めないとエラー扱いにしてしまうソフトの問題かと。
0198名無しさん@お腹いっぱい。
2014/08/06(水) 16:39:03.33サイズに関する進展。
まず、壁は4KBじゃなく、8KB。しかも8192byteちょうどならフリーズ。8191byteならOK。
あと、これは予想されたことだが、showpage\n がファイル末尾ならどんなサイズでもOK。1文字でも余計に続くとフリーズ。
で、だ。これが不可解なんだが、write(2) で一発でパイプに書くんじゃなく、
1バイトずつ、1024バイトずつ、4096バイトずつ、小分けに書くとフリーズしない。
もちろんこの間 read(2) していない。
なぜだ?誰か名推理してくれ。あるいは次に調べること提案してくれ。
どうも FreeBSD 固有の pipe の実装にぶちあたってきた気がしてならない。
あと蛇足だが衝撃の事実。gs は標準入力を1バイトずつ read(2) してる。
0199名無しさん@お腹いっぱい。
2014/08/06(水) 17:24:26.66>>197はどこからそう判断してるの?
0200名無しさん@お腹いっぱい。
2014/08/06(水) 18:28:48.130201名無しさん@お腹いっぱい。
2014/08/06(水) 20:46:12.80EPSにはshowpageがあるのと、showpageがないか無効化されてるのがあり、
後者はgsが入力の最後までちゃんと読むので、write(2) が完了し、
サイズによらずフリーズしない。
linux (Fedora 20) で LibreOffice 4.1.3.2 を使ってフリーズさせることに成功。
ただ条件がかなり狭い。
sinx.epsみたいなのに何MBも冗長な行を追加してもフリーズしない。
write(2) は何MBも一気にパイプに書いたが、なぜ可能か不明。
画像をpnmtopsしただけの1MB超EPSに数十KB冗長な行を追加するとフリーズした。
0202名無しさん@お腹いっぱい。
2014/08/06(水) 21:54:11.92・showpageが途中に来る(gsc入力終了前に出力が始まる)
・8KB以上の入力
・4KB以下を一括でwrite
の三条件で発生して、
・止まるときは4KB以上のwriteがブロックしたまま停止する
ってことか。showpageの情報と分割writeの情報で一気に予測が進むね。
4KB以上のwriteではwriteから抜ける条件が全データreadされること、なのかもね。
4KB超えたらパイプバッファが足りないからreadを待って続きをwriteってのありそう。
4KB以下なら大丈夫なのは、showpageの後ろが4KB以下だからバッファへwriteして抜けれるとか。
なら多分BMPサイズが4KB以下のもセーフかも。
FreeBSDのソース読んでみようかな。
0203名無しさん@お腹いっぱい。
2014/08/07(木) 02:47:40.62うげぇ・・・K&Rスタイルの引数指定かよ・・・
・・・よし、なんとなく把握した。202時点で想像した形と案外近かった、かな。
FreeBSDのパイプにはdirect I/Oってモード(pipe_build_write_buffer)があって、
これはカーネルにマップしたwrite側プロセスのメモリをパイプバッファとして使う。
一度にマップする量はpipe_buffer.size以下で、マップする前にバッファが空になるのを待つ。
マップするから当然、マップしたデータを全部readしてもらうまでwriteはブロックしたまま。
writeの時に残りのread待ちデータがバッファサイズ以下でもブロックするのは不味いねぇ…。
ってわけで対策考えてまとめてみた。間違ってたらごめんなさい。
・LOで出来る対策(根本治療)→横着しないでreadとwriteを並列に動かす(大事)。
・GSで出来る対策(根本治療)→showpageしても、readとwriteを並列に動かす(大事)。
・BSD User側対策(根本治療)→gscをシェルスクリプトとかで差し替え(>>144)。
・LOで出来る対策(対処療法)→writeを刻んだりシェルスクリプトを経由させたり(>>144>>198)。
↓100%対策じゃないけど、フールプルーフになる。
・BSD User側対策(対処療法)→PIPE_MINDIRECTを上げたりPIPE_NODIRECT有効でカーネル再構築。
・BSD Kernel改良(対処療法)→direct I/Oモードを使う場合も、バッファを活用する。
・バッファサイズを超えたwriteを抜ける時はバッファが満タンになるように、
pipe_build_write_bufferではpipe_buffer.size以下を全部マップせず、
writeの最後でuio->uio_residがPIPE_MINDIRECTかpipe_buffer.sizeになるよう制限する。
・uio.uio_residがwpipe->pipe_buffer.size以下ならpipe_direct_writeのmsleepは
無限待ちせずタイムアウトからのpipe_clone_write_bufferで抜ける。
所詮フールプルーフだからできるだけdirect I/Oで稼ぐ為タイムアウト。
■DEFINE設定値
PIPE_SIZE:pipe_buffer.sizeの最大値。デフォ16384。
PIPE_MINDIRECT:direct I/O自動選択の条件、PIPE_SIZEより小さい。デフォ8192。
PIPE_NODIRECT:pipe_direct_writeを使わせないフラグ。
■ このスレッドは過去ログ倉庫に格納されています