ちょっとややこしいdocument、window、screenの話
jQueryで画面の高さを取得する時、取得方法がいろいろあって
どれを使うべきか悩むことがあります。
主に
- $(document).height()
- $(window).height()
- screen.height
- screen.availHeight
これらはそれぞれ
$(document).height(): 読み込んだページの全高さ
$(window).height(): ブラウザ中のスクロール部分の高さ
screen.height: デバイスの画面のサイズ
screen.availHeight: デバイスの画面サイズからOSのメニューバーやタスクバーを引いた高さ
なので、
$(document).height() > $(window).height()のときに、すべてを表示しようとすると、画面のスクロールが必要となります。
$(window).height()はブラウザのディベロッパーツールを表示したり、ブラウザのツールバーを表示するとサイズが小さくなります。
javascript - Difference between screen.availHeight and window.height() - Stack Overflow
Ruby拡張ライブラリをデバッグする
静的リンクもしくは動的リンクでデバッグする方法があるようです。
今回は動的リンクでやってみました。
題材はpcaprubというRubyからpcapファイルを使うためのライブラリです。
ライブラリを使うa.rbから、test.pcapファイルを読み込むためにpcaprubを使います。
デバッグシンボルはあったほうがデバッグしやすいので、
拡張ライブラリを-gつきでコンパイルしておきます
gdbを起動します
$ gdb ruby
とりあえずmainにブレークポイントをはって、起動します
(gdb) b main (gdb) r a.rb test.pcap
Ruby は dln_loadでライブラリを読み込むようです
そこにもブレークポイントをはって、実行を再開します
(gdb) b dln_load
(gdb) c
ライブラリのロード部分でブレークします
encdb.soが読み込まれました
Breakpoint 2, dln_load (file=0x737400 "/home/yu74n/.../enc/encdb.so") at dln.c:1250
確認してみましょう*1
(gdb) i sharedlibrary From To Syms Read Shared Object Library (*snip*) 0x00007ffff619b680 0x00007ffff619c2b8 Yes /home/yu74n/.../enc/encdb.so
デバッグしたい拡張ライブラリが現れるまでスキップします
(gdb) c Continuing. Breakpoint 2, dln_load (file=0x8a9b90 "/home/yu74n/.../pcaprub.so") at dln.c:1250
現れたので確認してみます
(gdb) i sharedlibrary 0x00007ffff5d918c0 0x00007ffff5d94058 Yes /home/yu74n/.../pcaprub.so
ありましたね
あとはデバッグしたい場所にブレークポイントをはると
ブレークします
(gdb) b rbpcap_next_packet Breakpoint 3 at 0x7ffff5d92520: file pcaprub.c, line 802. (gdb) c Continuing. Breakpoint 3, rbpcap_next_packet (self=8914880) at pcaprub.c:802 warning: Source file is more recent than executable. 802 {
ソースを見てみます
(gdb) l 797 * If the next_packet() is unsuccessful, Null is returned. 798 */ 799 800 static VALUE 801 rbpcap_next_packet(VALUE self) 802 { 803 rbpcap_t *rbp; 804 rbpcapjob_t job; 805 char eb[PCAP_ERRBUF_SIZE]; 806 int ret;
*1:ブレークしてしばらくnextで進んだ後に実行してください
mongo shellから検索クエリはわかるけど、Rubyドライバでの書き方がわからんときの解決法
BSONなので、BSON経由で変換すればいい話ですね。
例えば、下のようなMongoDBドキュメントがあったとします。
{ "_id" : ObjectId("51b6f5414eba1e94ba5bf762"), "info" : { "category" : "file", "started" : "2013-06-11 18:59:52", "ended" : "2013-06-11 19:00:48", "version" : "0.5", "duration" : "55 seconds", "id" : 3921 } }
info.startedは開始日時を表しており、これを使ってフィルタをかけたいとします。
mongo shell で書くとこんな感じです。
{ "info.started": {$gte: "2013-06-10",$lt: "2013-06-11"}}
当たり前ですが
Rubyドライバで以下のようにすると、データ量にもよりますが死ぬほど時間がかかります。
coll.find().each do |doc| # ここでフィルタ end
find()の第1引数でフィルタをかけるべきですが、複雑なMongoDBドキュメントになればなるほど、
どういうふうに書けばいいかわからなくなります。
ドキュメントには基本的な構文しか載っていません。
MongoDBの検索クエリはBSON形式なので、mongo shellで書いた検索クエリをBSON形式に変換し、
Rubyドライバでデシリアライズすればよさそうです。
mongo shellはJavaScriptなので、JS用のドライバで検索クエリをシリアライズします。
MongoDBにはjs-bsonというライブラリがついていて、ブラウザからも使えます。
js-bson
https://github.com/mongodb/js-bson
browser_build/bson.jsを適当な場所に配置して、同じフォルダに以下のファイルを置きます。
js-bsonのREADMEに書いてあったものを持ってきて、コンソール出力するように修正しただけです。
<head> <script src="./bson.js"> </script> </head> <body onload="start();"> <script> function start() { var BSON = bson().BSON; var Long = bson().Long; var doc = {//ここに検索クエリを書く} // 例えばこんな感じ // var doc = {"info.started": {$gte: "2013-06-10",$lt: "2013-06-11"}} var data = BSON.serialize(doc, false, true, false); console.log(data) } </script> </body>
これでBSON形式の検索クエリがブラウザのコンソールに出力されます。
ChromeであればF12キーを押して、consoleタブに移動するだけです。
BSON形式のバイナリは10進数の配列で表示されます。
16進数でRubyでデシリアライズできる形式に変更したいので、Rubyで成型します。
require 'bson' # ブラウザに表示された配列をコピーしてirbの変数に代入します。 bson = [65, 0, 0, 0, 3, 105, 110, 102, 111, 46, 115, 116, 97, 114, 116, 101, 100, 0, 46, 0, 0, 0, 2, 36, 103, 116, 101, 0, 11, 0, 0, 0, 50, 48, 49, 51, 45, 48, 54, 45, 49, 48, 0, 2, 36, 108, 116, 0, 11, 0, 0, 0, 50, 48, 49, 51, 45, 48, 54, 45, 49, 49, 0, 0, 0] # 16進数に変換します hex = bson.map {|x| "%02X" % x} # 結合します msg << hex.join # Rubyのバイナリ形式に変換します bin = msg.pack("H*") # BSON形式をデシリアライズします BSON.deserialize(bin.unpack("C*")) # => {"info.started"=>{"$gte"=>"2013-06-10", "$lt"=>"2013-06-11"}}
あとはこの検索クエリをRubyドライバから使うだけです。
*nix系OSの起動時のデーモン(サービス)起動について
はじめに
デーモンとして起動するmongodbのオプションを追加/変更したかったのだけど、
*nix弱者で、*nix系OSの起動時の仕組みがよくわかっていないので、メモしておきます。
結論
textSearchEnabledを設定ファイルに書けって話ですね。
結論としては/etc/init/mongodb.confのstart-stop-daemonの--execの部分を変更すればいいってとこに落ち着いたけど、あってるかは不明。
# Text Searchを有効にするなら if [ "x$ENABLE_MONGODB" = "xyes" ]; then exec start-stop-daemon \ --start --quiet --chuid mongodb --exec /usr/bin/mongod -- \ --setParameter textSearchEnabled=true --config /etc/mongodb.conf; fi
init.d
起動時にOSがごにょごにょして/etc/init.dの下にあるスクリプトが実行されるようです。
スクリプトを見てみます。
ちなみにmongodbのスクリプトを見てみます。
... INITSCRIPT="$(basename "$0")" JOB="${INITSCRIPT%.sh}" ...
$(basename "$0")はコマンド置換ですね。
$0は位置パラメータという組み込み変数でスクリプト名に置換されます。
# INITSCRIPT="$(basename "$0")" は # INITSCRIPT="$(basename "/etc/init.d/mongodb")" になり # INITSCRIPT="mongodb" になる INITSCRIPT="$(basename "$0")"
${}はパターン照合演算子というやつで
${val#pattern}はvalの先頭からpatternに一致した最も短い部分を削除し、残りを返す
${val%pattern}はvalの末尾からpatternに一致した最も短い部分を削除し、残りを返す
# JOB="${INITSCRIPT%.sh}" は # 末尾に.shがあれば、それを削除して残りの部分を返す
起動の部分がみたいので、startの所を見てみる。
# $COMMAND には/etc/init.d/mongodb start でいうstartがはいり # $JOB にはmongodbが入る # start mongodb が実行される $COMMAND "$JOB"
startっていうコマンドがあるらしい。
man startをしてみるとinitctl(8)が表示された。
/sbin/startはinitctlへのシンボリックリンク
file `which start`
UpStart
これはUpStartっていうらしい
# /etc/init.d/mongodb はupstart-jobへのシンボリックリンク /etc/init.d/mongodb -> /lib/init/upstart-job
んで、UpStartの設定として、ジョブ定義というものがあるらしい
ubuntuの場合は/etc/init/mongodb.confになる
その中にscript 〜 script endと書くことでシェルスクリプトをそのまま書けるらしい
script ENABLE_MONGODB="yes" if [ -f /etc/default/mongodb ]; then . /etc/default/mongodb; fi if [ "x$ENABLE_MONGODB" = "xyes" ]; then exec start-stop-daemon \ --start --quiet --chuid mongodb --exec /usr/bin/mongod -- \ --config /etc/mongodb.conf; fi end script
ENABLE_MONGODB="yes"は意味がわからなかった。
/etc/defaultは追加設定を置いておく場所らしい。
その後、start-stop-daemonが実行される。これはプログラムを簡単にデーモン化するものらしい。
ubuntuでLauncher起動のショートカットキーを変更する
備忘です。
ubuntuホスト上でWindowsゲストを動かすとき、Superキー(Windowsキー)にLauncherの起動が割り当てられていると何かと不便なため、他のキーに割り当てたくなります。
# ファイル名を指定して実行(Win+R)のときにLauncherが起動して不便というのが一番大きい
結論からいうとCan I define keyboard shortcuts using the Super key?に解決方法は書いてあるのですが、alt+f2からabout::configとしてもなにも起こらなかったので、自分用にめもっておきます。
compizconfig-settings-manager パッケージのインストール
sudo apt-get install compizconfig-settings-manager
を実行
CompizConfig設定マネージャーの起動
Launcherを起動してComと入力すると「CompizConfig設定マネージャー」が見つかるので起動する。
キーの変更
CompizConfig設定マネージャーのデスクトップ項目にあるUbuntu Unity Pluginを選択し、Behaviourタブの「Key to show the launcher」を変更したいキーに設定する。
WDKドライバ開発 - Visual Studio の設定
おことわり
こういう自分用めもは非公開にすべきなのですが
はてな Blog では記事ごとの公開/非公開設定ができないみたいなので、
最初に言っておきます
VC++をドライバ開発環境にするの自分用めもです。
参照元のサイトのほうが画像つきで丁寧なので、そちらを参照してもらったほうがよいです。
環境
- Visual Studio 2010 (高価な専門ツールです)
- Windows Driver Kit Version 7.1.0
- ddkbuild_cmd 2009-11-28@04-38-36
下準備
- WDKは入っている前提
- ddkbuild.cmdをダウンロードする
- 適当な場所(UACでとめられない場所が望ましい)に作業用ディレクトリを作成しとく(スペースとか全角文字とかは含まれないようにしとく)
- DLしたddkbuild.cmdをwdkディレクトリの下に置く(まぁどこでもよいのだが)
- ddkbuild.cmd の @echo off の下にビルドする環境に合わせて、以下のような設定を書いておく
@set W7BASE=C:\WinDDK\7600.16385.1
プロジェクトの作成
新しいプロジェクトを作成からメイクファイル プロジェクトを選択する
そのほかのファイル
ソースファイルを.cファイルとして作成
ビルドするためなら、DriverEntryだけ書いておけば、とりあえず通る
#include <ntddk.h> #include <wdm.h> NTSTATUS DriverEntry( PDRIVER_OBJECT pDriverObject, PUNICODE_STRING RegistryPath ) { DbgPrint("Hello World\n"); return STATUS_SUCCESS; }
sources
TARGETNAME はプロジェクト名
TARGETTYPE はドライバ作成の場合はDRIVER
TARGETLIBS はドライバ作成で使うライブラリを書いておく
SOURCES はビルドするファイルを書いておく
USE_PDB はないと後(デバッグ時)から泣くことになるので入れておく
TARGETNAME=test TARGETTYPE=DRIVER TARGETLIBS=$(SDK_LIB_PATH)\advapi32.lib \ $(SDK_LIB_PATH)\ntdll.lib \ $(SDK_LIB_PATH)\kernel32.lib \ $(DDK_LIB_PATH)\ntoskrnl.lib \ $(DDK_LIB_PATH)\ndis.lib \ SOURCES=\ driver.c \ USE_PDB=1
makefileとsourcesファイルに.txt拡張子をつけないようにする
インテリセンスを有効にする
プロジェクトのプロパティを開き、NMAKE->インクルードの検索パスに(WDKのパス)\inc\ddkを追加する
ドライバのロード
わざわざローダを書くのが面倒な場合は
Driver Loader(OSR Online に登録が必要)を使いましょう
ただし Windows XP までしか対応していません
Windows XP 用にドライバを作成するには
ロードの確認
Sysinternals Suite の DbgView を使いましょう
メニューの Capture->Capture Kernel を有効にする