Mac OS X QSystemTrayIconのactivated()を受けたスロット延長でhide()するとクラッシュする件
環境:Mac OS X + Qt 5.3.2 QSystemTrayIconでQSystemTrayIconのactivated()シグナルを受けたスロットの延長でQSystemTrayIcon::hide()するとクラッシュする件。
なんっどやっても内部クラッシュするのでなんでだー!!ってなってたけど、Qt内部のバグによるもので、回避策を打たないと100%クラッシュします。例を挙げて解説します。
QSystemTrayIconをクリックしたら対象のアイコンを隠したい時があったので、以下のようにコードを書きました。まず
QSystemTrayIcon *systray = new QSystemTrayIcon(this); connect(systray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
こんな感じで普通にconnectします。で、スロットの方では以下のように
void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason){ switch (reason) { case QSystemTrayIcon::Trigger: case QSystemTrayIcon::DoubleClick: case QSystemTrayIcon::MiddleClick: systray->hide(); break; default: break; }
まあ、至って普通に見えますね。が、これを動作させると大体以下のような感じで落ちます。
Crashed Thread: 0 Dispatch queue: com.apple.main-thread Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: EXC_I386_GPFLT Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libqcocoa.dylib 0x0000000103f47787 -[QNSStatusItem triggerSelector:button:] + 71 1 libqcocoa.dylib 0x0000000103f472a5 -[QNSImageView mousePressed:button:] + 405 2 com.apple.AppKit 0x00007fff90b4150e -[NSWindow sendEvent:] + 6853 3 com.apple.AppKit 0x00007fff90f2b29e -[NSStatusBarWindow sendEvent:] + 67 4 com.apple.AppKit 0x00007fff90b3d644 -[NSApplication sendEvent:] + 5761 5 libqcocoa.dylib 0x0000000103f22b0e -[QNSApplication sendEvent:] + 78 6 com.apple.AppKit 0x00007fff90a5321a -[NSApplication run] + 636 7 libqcocoa.dylib 0x0000000103f1f1d4 QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 2420 8 QtCore 0x000000010096bacd QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 381 9 QtCore 0x000000010096f007 QCoreApplication::exec() + 359 10 TEDT.RapidCopy 0x0000000100005bcc main + 236 11 TEDT.RapidCopy 0x00000001000057c4 start + 52
解決法は以下のようにすればokです。
void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason){ switch (reason) { case QSystemTrayIcon::Trigger: case QSystemTrayIcon::DoubleClick: case QSystemTrayIcon::MiddleClick: //Mac OS XのQtバグ回避 QMetaObject::invokeMethod(systray, "hide", Qt::QueuedConnection); break; default: break; } }
この現象はmacosxのバグとのことで、Qt4.xからずっと対処されていない問題のようです。
Qtをお使いの方ならご存知、何でも答えてくれるVokerさんが答えてくれています。
QSystemTrayIcon hide() crash on mac while I use QTimer to change the icon of QSystemTrayIcon | Qt Project forums | Qt Projectで、ちょっとつらいのがこの問題、Qt4.xのドキュメントには補足されてます。
QSystemTrayIcon Class Reference | Documentation | Qt Project
が、Qt5では補足が引き継がれていません。。
QSystemTrayIcon Class | QtWidgets 5.3 | Documentation | Qt Project
Qt5の補足にコピペで書いておいてあげないとと思ったのですが、投稿の仕方がわからず(´・ω・`)
誰か投稿の仕方教えてください。。
落ち方をぐぐってこの記事にたどり着く人が出たらいいなあと思ってます。
めっちゃわからずにはまったよー(´;ω;`)
2014/11/24訂正:
日本qtユーザー会の
Tasuku Suzuki (@task_jp) | Twitterさんからqtのバグであること、
またバグ回避方法のオススメについて教えて頂いたので、記事内容を訂正しました。
ありがとうございます(._.)
qtbugレポートへのリンクは以下の通りです。
https://bugreports.qt-project.org/browse/QTBUG-6328
特定ディレクトリに特定の名称のフォルダを作成したらメール飛ばして検知するRubyコード
約半日で適当に書いたのでうp。異常系はなんも考慮してないけどとりあえず動く。
前提はRuby1.8.7
起動時に勝手にデーモンとして仕込む話題はまた別途投稿かなー。
#!/usr/bin/env ruby
################################################################################
# 名前:WatchFolder.rb
# 目的:特定の名称のディレクトリ作成を監視する。
# 機能:第一引数に指定したディレクトリ配下に特定の文字列でディレクトリを作成した時、
# 特定のメールアドレスに検知メールを送信する。
# 第一引数:監視したいディレクトリの絶対パス。
# 作成日:2013/05/13
# 作成者:澤津健吾
# 特記事項:監視対象は0-9の文字列で始まるディレクトリ。
# 例:130331_aikatsuとか100531_sawatsu_kimoiとか。
# 上記以外のフォルダを作成しても何もしない。
# 引数チェックは行わない。仕込んだ後の動作チェック忘れないでね。
# まともなエラー処理は期待するな。
# 本プログラムの動作にはfssmとtmailをインストールする必要がある。
# デーモンとしてしれっと常駐させるのを想定してるよ。
################################################################################
require 'rubygems'
require 'fssm'
require 'tmail'
require 'socket'
require 'net/smtp'
#FSSMモニターで無限ループするよ。
#監視対象のパスは第一引数に指定したやつね。
#監視対象のディレクトリ名については特記事項参照
FSSM.monitor(ARGV[0].to_s, '**/[0-9]*', :directories => true) do
update do|base, file|
#ファイル更新の出口なんて興味ないよ。
end
create do|base, file|
#ファイル作成の出口は興味あるよ
#出来たファイルの詳細情報取るべかな。
stat = File.stat("#{base}" + "/" + "#{file}")
#FSSM側で判定してるけど、なんとなくもっかいチェックしとく。
#ファイルがディレクトリかな?
if(stat.directory?)
#対象はディレクトリだな。
watchdirname = "#{base}" + "/" + "#{file}"
#Mail送る準備すっかー。
#まずはホスト名をそれっぽく取得、Macの場合は***.localとかやな。
hostname = Socket::gethostname
mail = TMail::Mail.new
#複数送信する場合は,区切りで文字列送り込めばよかったらしい。
#設定ファイル読み込みとかはめんどくさいしなー。
#宛先は随時必要に応じて変えたりしてください。
mail.to = 'hoge@hoge.co.jp,hoge@hoge.co.jp'
#送信元メールアドレス設定
mail.from = "#{hostname}@hoge.co.jp"
#サブジェクト作成
mail.subject = "#{hostname} Project folder create detected."
#送信時刻設定
mail.date = Time.now
#MIMEversion設定
mail.mime_version = '1.0'
#本文設定する。フォルダ作成時刻は厳密にはstatから拾うのがいいんだろうけど
#Windowsとか、異機種から適当に作られたりとかLTFSとか、アテにならない奴もいるので
#プログラム実行時の時刻で代用。精度が大事なワケじゃないからいいでしょ?
mail.body = "project Folder create detected.\n" +
"created Folder path = #{watchdirname}\n" +
"created Time = " + Time.now.to_s + "\n"
mail.set_content_type 'text', 'plain', {'charset'=>'iso-2022-jp'}
#メール送信サーバ設定はそれっぽく必要に応じて変えたりしてください
Net::SMTP.start('38.38.38.38',25) do |smtp|
smtp.sendmail( mail.encoded, mail.from, mail.to)
end
else
#対象がファイルなんで興味ないよ
end
end
delete do|base, file|
#ファイル削除の出口なんて興味ないよ
end
end
データストレージEXPO2013春 簡易レポート
ArecaのRAIDカードとST3000DM001タイムアウト問題
ArecaのRAIDカードとST3000DM001の相性問題について。
日本でまともに語ってる人見たことないので、載せておきます。
環境:
RAIDカード: Areca ARC-1882 or Areca ARC-1880
ファームウェアVer:FW1.49~1.51(1.49より古いVerでも恐らく発生する)
クライアント:MacPRO(原因が正しいとするならば、Windowsでも発生する)
HDD:ST3000-DM001
HDDファームウェアVer:CC4H
現象その1:ArecaのRAIDカードとST3000-DM001を組み合わせてRAIDセットを組むと、TimeoutErrorが発生し、性能が急速に低下する。
現象その2:現象1の延長でArecaのstatusがDegradeに落ちる。
現象その3:Mac環境の場合には現象1結果としてOSフリーズとなり、強制電源断以外何もできなくなる。
原因:ST3000-DM001のファームウェアバグ。
ST3000-DM001はAFTディスクであり、セクタ長は4096バイトである。
しかし、旧来のOSやソフトウェアの中には512バイトセクタを
暗黙に仮定しているものが多数ある。
ST3000-DM001は512バイトセクタを暗黙的に期待するデバイスのための、
512バイトセクタHDDエミュレーション機能が存在する。
Arecaは仕様として、512バイトセクタでHDDとデータのやり取りを行う。
この時、ST3000-DM001側のエミュレーション機能に問題が発生し、
Areca側にデータを一定時間送信しなくなる。
Areca側はデバイスタイムアウトと判定、タイムアウト時間の設定値に
よってはRAIDセットのデグレードとして認識されてしまう。
対策:なし。
Areca側のタイムアウト値を伸ばすことでデグレードは回避できるが、
本質的な対策はない。
Concerning the compatibility issues ST3000DM001 and RAID cards Areca.
Because I've never seen people who are told decent in Japan, I'll put.
Environment:
RAID Card: Areca ARC-1882 or Areca ARC-1880
RAID Card Firmware Ver 1.49 ~ 1.51
(I probably occur even older than Ver 1.49)
Client: MacPRO (If the cause is right, Windows even occur)
HDD: ST3000-DM001
HDD firmware Ver: CC4H
Symptom1: When for RAID set using a combination of ST3000-DM001 and RAID card of Areca, TimeoutError occurs, performance decreases rapidly.
Symptom2:Status of Areca fall to Degrade
Symptom3: it becomes OS freeze as a phenomenon one result in the case of the Mac environment, you will not be able to do anything other than force power-off.
Cause: ST3000-DM001 Firmware Bug.
ST3000-DM001 is AFT(Advanced Format Sector) disk, sector length is 4096 bytes.
However, there are many things that are implicitly assumed a 512-byte sectors in the OS and software legacy.
ST3000-DM001 is for the device to expect implicitly 512-byte sectors,
512-byte sector HDD emulation function exists.
As a specification, Areca to exchange data with the HDD in 512-byte sector.
At this time, some problem occurs in the emulation function of ST3000-DM001 side,
I will not send a certain period of time the data on Areca side.
It becomes time-out detection device from Areca side,
It would have been recognized as degraded the RAID set by setting the value of the time-out period.
Measures: none...
Degraded can be avoided by extending the time-out value of Areca side, but no measures essential.
今更ながらはてブ?を始めてみました
知っている方も知ってない方もこんにちは、KengoSawa2です。
最近色々忘れる事増えてきました。。
感想とか感情的なモノをできるだけ排除した、ハードソフトネットワークをそれぞれごっちゃにした技術情報をばんばか書いていこうかなーとおもっちょります。
評価の仕方とか、こんな情報アルヨ等あれば是非突っ込んであげてください。