🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Qt Creator

Qt Creatorは、Qtアプリケーションを開発するための開発統合環境(IDE)です。

Q&A

解決済

2回答

2256閲覧

FRAM(mtdblock4)をQFileを使って開きseek関数を呼ぶと警告が出てくる問題

tuyudaku

総合スコア75

C++11

C++11は2011年に容認されたC++のISO標準です。以前のC++03に代わるもので、中枢の言語の変更・修正、標準ライブラリの拡張・改善を加えたものです。

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Qt Creator

Qt Creatorは、Qtアプリケーションを開発するための開発統合環境(IDE)です。

0グッド

0クリップ

投稿2019/10/09 06:18

編集2019/10/09 08:18

FRAM(/dev/mtdblock4)のデバイスファイルをQFileで開き
seekで所定の位置まで移動して、wirteでデータを書く
という流れの処理をしています。

コンパイルのQtバージョンは5.3.2で、実行環境もQt5.3.2
の状態でアプリを起動すると、seekを呼んでいるところで

QIODevice::seek: Cannot call seek on a sequential device

というエラー?警告?文が表示されます。

言葉通りなら
シーケンシャルデバイスではシークできないよと言っているのだと思います。
確かにQtのドキュメントにも

For sequential devices, the default behavior is to do nothing and return false.

と書いているため、シーケンシャルデバイスの場合何もしないということになります。
seekの戻り値がfalseになっていたことも確認済みです。
しかし、実際にFRAMの中身を見てみると
しっかりとシークをした位置にデータを書き込んでいることが確認できました。
というかそもそもFRAMはランダムアクセスだと思うので、前提の部分でおかしいです。
isSequentialを呼んでみるとfalseが返ってくるため、しっかりとランダムアクセスデバイスとして
認識は出来ているみたいです。

また、コンパイルしたものはそのままで実行環境をQt5.7.1で実行してみると
問題の警告文が表示されなくなります。
このことからQtのバグなのではと推測したのですが
これに関するバグレポートや修正に関する文書が見つけられず困っています。

これがただ単に間違って警告が出てしまうだけだというなら、
表示される警告を無視、出来れば表示しないようにしてそのままQFileseekを使い続けようと思っているのですが
他に致命的なバグが存在するようなのであれば、C++の関数に処理を書き換えようと思っております。

何かコレに関する情報をご存知の方、ちょっとしたことでもいいので教えていただけませんでしょうか?
よろしくお願いします。

###追記
Qt5.3.2のソースを見ていたところ

C++

1bool QIODevice::isSequential() const 2{ 3 return false; 4}

というのを見つけました
つまりどんな状況でもfalseしか返さないので、実質シーケンシャルデバイスを認識するのは不可能?
そうなってくるとなぜ警告文が出てくるのか、なおさら分からなくなってしまいました...

###追記2
QFile::seek() on character devices not working
該当の問題だと思われるバグのページを見つけていました...
割と最初に見つけていたのに勝手に勘違いしてスルーしていました...

恐らくこれだと思われるので
今一度、検討をしてみたいと思います

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2019/10/09 06:37

何らかの組み込みlinux上の話でしょうか。/dev/mtdblock 用のデバイスドライバーは自作(あるいはベンダー提供)のものではありませんか。
tuyudaku

2019/10/09 06:43

>何らかの組み込みlinux上の話でしょうか はい、ボードコンピュータにDebianがインストールされているものです >/dev/mtdblock 用のデバイスドライバーは自作(あるいはベンダー提供)のものではありませんか。 ベンダー提供になります
guest

回答2

0

ベストアンサー

Qtを使ったことは無いのですが、「ちょっとしたことでもいいので」とのことでしたので、ご質問を読んで思ったことを述べたいと思います。ですのでQtから離れ、かつ直接的な回答ではありませんのでご了承ください。

FRAMはメモリなので、本来はディスクのようなブロックデバイスに相当するものだと思います。それを上位のアプリ側への便宜を図って /dev/mtbblokへのデバイスドライバーを介し、必要に応じてデバイスドライバーが提供するioctlで固有のコマンドを受け付け、さもファイルでシークできるように振る舞います。

ベンダー提供のデバイスドライバーであれば、カスタマイズされたボード用にベンダーがそれ用のデバイスドライバーを提供しますが、もともと用途が限定されているので機能に制限があったり、使い方によってはもちろんバグや不具合が出ることもあります。/dev/mtbblockを直接アクセスしていることで、それらのことが発現しているかもしれません。
例えばファイルのシークはlinuxのシステムコールlseek

Linux man(2) - lseek

ですが、呼び出せはしてもFRAMへのアクセスに関してドライバー内の処理に不備があれば、返ってくる結果が不整合となることも有り得ます。そんな場合、Qtから降りてC++でファイルアクセスするようにしても、恐らく本質的に同じ結果になります。

問題の切り分け方法としてご提案できることのひとつは、Qtでもなく、C++でもなく、C言語でlinux のopen, lseek, read, writeなどのシステムコールを直接使うテストプログラムを作り、それらシステムコールの呼び出し結果(返り値)とerrnoを確認し、また、実際の読み出し、書き込み結果を照合してみることです。特にエラー時に参照できるグローバル変数errnoは通常、デバイスドライバーが返すものなので、時に有用なものになります。

場合によってはベンダー提供のデバイスドライバーのソースと突き合わせてみる必要もあるかもしれません。ここで問題があるのであれば少々やっかいで、問題の無い /dev/mtblockへのアクセス方法を考えなければなりません。あるいはデバイスドライバーの改修か。

もちろん、Qtのライブラリとのインターフェース不整合と言うこともあります。そうであれば、C++でのファイルアクセスで回避策を得られると思いますし、別回答でいただいた策や、追記されたことの裏づけも取れると思います。

投稿2019/10/09 07:25

dodox86

総合スコア9254

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2019/10/09 07:29

コメントの > そうなってくるとなぜ警告文が出てくるのか、 ですが、bool QIODevice::isSequential() const { return false;} を受けての、Qtの上位ライブラリが出している単なる警告かアサーションかもしれませんね。(推測です)
tuyudaku

2019/10/09 07:34

>FRAMへのアクセスに関してドライバー内の処理に不備があれば なるほど、考えもしていませんでした 確かに、その場合は厄介ですね >システムコールの呼び出し結果(返り値)とerrnoを確認し、また、実際の読み出し、書き込み結果を照合してみることです これは一度しておいたほうが良いかもしれませんね とてもためになる回答ありがとうございます 勉強になりました
tuyudaku

2019/10/09 07:39

>Qtの上位ライブラリが出している単なる警告かアサーションかもしれませんね。 seek関数内で isSequentialの戻り値がtrueの場合、問題の警告を表示して その場でfalseをreturnするところまでは確認できているのですが じゃあ必ずfalseなら何故警告が? seekの戻り値がfalseなのは確認できているが なら何故シークできているのか? と、謎が深まるばかりです... 軽くしか見ていないのでよく見れば解決するかもしれないので 問題を追っかけるのも良いですが、そこに時間をかけすぎてもしょうがないので とりあえず使用を避けることにしたいと思っています システムコールでの処理が確認でき次第 そのままその処理を採用しようかと思っています
dodox86

2019/10/09 07:45

> seekの戻り値がfalseなのは確認できているが > なら何故シークできているのか? /dev/mtbblock のデバイスドライバーを利用したread/write/lseekはちゃんと動いていて、シーケンシャルデバイス(キャラクターデバイスのことだと思いますが)か否かの判定を決定付けるQtのライブラリか、ドライバーとのやり取りにどこかに不備があるのだと思います。その場合は、問題は軽微だと思います。(状況を理解した上で、無視すれば良い)
tuyudaku

2019/10/09 08:16

>シーケンシャルデバイス(キャラクターデバイスのことだと思いますが) この文に、ん!? と思い、検索したサイトを見返してみました https://bugreports.qt.io/browse/QTBUG-63099 恐らくこれですね...割と一番最初に見つけていましたが character devicesというワードに違うかな?と勘違いしてスルーしていました... ちゃんと読んではいませんが 恐らくこのバグで間違いないかと思います だとするとページにも書いてある通り軽微なバグだとは思います もう少し使用するかどうかを検討してみたいと思います seekの頻度が多いためそのたびに警告が出るのは困るので 回避できないかの検討が必要です...
dodox86

2019/10/09 08:25

ご案内いただいたQtのバグレポートを読みました。まさにキャラクターデバイスに対するQFile::seek()ハンドリング不備、ですね。
dodox86

2019/10/09 08:30

とは言え バグレポート中の以下の dと fileEngine、QIODeviceのクラスの内容を読まないと断定はできませんが。 if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) 開いたファイルへのseekをサポートするかしないか、ユーザー側でフラグをセットするメンバー関数があるのではないでしょうか。(あってもバグレポートにあるように、処理が足りなそうですが) 思いつきの助言ですので、この辺にしておきます。
guest

0

Qt の開発は、「バグの修正時には必ずバグ登録をする」というルールでは行われていないため、修正されたバグに対応するバグレポートがない場合があります。

どの修正によってその振る舞いが変わったかを確かめたいのであれば、 Qt 5.3.2 と Qt 5.7.1 を git bisect して、コミットを特定することをお勧めします。

本日時点での Qt は最新版は 5.13.1 となっており、Qt 5.7.1 以降に発見されたバグがいくつも修正されています。

致命的なバグを気にされるのであれば、まずはサポート対象の最新版もしくは最新のLTS版(本日時点では 5.12.5)を使うことを強くお勧めします。

投稿2019/10/09 06:53

tasuku.

総合スコア347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tuyudaku

2019/10/09 07:00

>「バグの修正時には必ずバグ登録をする」というルールでは行われていないため なるほど、必ずあるものだと勝手に思っていました >致命的なバグを気にされるのであれば それもそうですね... ただ、現状5.3.2(jessieでapt出来る最新)という方針になっているので 大人しくC++の関数で実装しようかと思います 回答ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問