Waylandを効果的にデバッグするために
「Wayland」を効果的にデバッグするために、「Wayland」デバッグツールが開発されました。カスタムプロトコルやコンポジターと連携して動作するプログラムを開発する開発者向けの内容です。
用語の紹介
まず用語の紹介です。オブジェクト(Object)
Waylandオブジェクトは抽象的な概念であり、クライアント側でもサーバー側でもオブジェクトを通じて機能のやり取りを行います。例えば「libwayland」をC/C++で利用しているなら、クライアント側のオブジェクトは「wl_proxy」であり、サーバー側のオブジェクトは「wl_resource」になります。
オブジェクトID
各Waylandオブジェクトは、数値IDにより識別されます。(オブジェクトID)この識別子はクライアント・サーバー間の接続毎に一意の値であり、接続が異なればこの識別子が重複することもあります。
例えば異なるクライアントプログラムが同じサーバーに接続すると、それぞれの接続で同じオブジェクトIDが割り振られる可能性があります。
また同じ接続でも、あるオブジェクトIDを持ったオブジェクトが破棄された後、新規にオブジェクトが生成されると、破棄され未使用となったオブジェクトIDがそのオブジェクトに再割り当てされることもあります。
メッセージ(Message)
Waylandオブジェクトはメッセージのやり取りを行うためのオブジェクトであり、いかなる種類のプロパティーも保持していません。クライアントからサーバーに対して送られるメッセージは、リクエストと呼ばれます。
逆にサーバーからクライアントに対して送られるメッセージは、イベントと呼ばれます。
メッセージは複数の引数を持つことができ、各引数の型には数値や文字列、Waylandオブジェクトといった様々な型を持つことができます。
「new_id」型を引数に持つメッセージは、新規オブジェクトの生成要求を行うメッセージです。
プロトコルとプロトコル拡張(Protocol/Protocol Extension)
Waylandプロトコルは、XMLファイルで定義されています。「Wayland」のコアとなるプロトコルは、「wayland.xml」で定義されています。
... <interface name="wl_display" version="1"> <description summary="core global object"> The core global object. This is a special singleton object. It is used for internal Wayland protocol features. </description> <request name="sync"> <description summary="asynchronous roundtrip"> The sync request asks the server to emit the 'done' event on the returned wl_callback object. Since requests are handled in-order and events are delivered in-order, this can be used as a barrier to ensure all previous requests and the resulting events have been handled. The object returned by this request will be destroyed by the compositor after the callback is fired and as such the client must not attempt to use it after that point. The callback_data passed in the callback is the event serial. </description> <arg name="callback" type="new_id" interface="wl_callback" summary="callback object for the sync request"/> </request> ...
これに加えプロトコル拡張(独自プロトコルの定義)を利用することも可能です。
プロトコルはオブジェクトの種類とどのようなメッセージを扱うのかを定義します。
またプロトコルを定義したファイルは、タイプセーフな言語バインディングの生成にも使用されます。
デバッグの基本
「Wayland」の問題の調査にあたり、まず初めにどのようなメッセージが送られているのかを把握する必要があります。メッセージのダンプ
「WAYLAND_DEBUG」環境変数に以下の値を指定すれば、メッセージのダンプが可能になります。- client
- server
- 1(clientとserverの両方が対象)
これにより送ったメッセージや受け取ったメッセージがすべて「stderr」に出力されます。
煩雑なメッセージの出力
メッセージの出力は非常に有用な内容ですが、このままでは不便です。メッセージが非常に数多くあり、必要なメッセージのみを抽出する正規表現を記述するには、長い記述が必要になってしまい手間がかかります。
特定のオブジェクトのメッセージを追跡し、その内容をファイルにリダイレクトする際、そのオブジェクトのIDを調べそのIDを元にメッセージを検索することになります。
しかしオブジェクトIDは再利用されるため、オブジェクトIDでメッセージを追跡することは非常に困難です。
またなぜそのメッセージが送られたのかを知るのは不可能ですし、サーバーをデバッグする際、複数のクライアントから接続されている場合、各クライアントを明確に識別しながらデバッグすることも困難です。
加えて探し求めているメッセージをピックアップすることもこのままでは困難です。
Waylandデバッグツールの開発
というわけで上記の課題をすべて解消したWaylandデバッグツールが開発されました。Wayland Debugの機能
「Wayland Debug」を利用すると、以下のようにメッセージの出力がハイライト表示されます。もちろん「Wayland Debug」が持つ機能はシンタックスハイライト機能だけではありません。
メッセージのフィルタリングや、オブジェクトIDが再利用されても各オブジェクトを識別する機能、複数の接続を適切に処理する機能、メッセージでブレークする機能など、デバッグに有用な機能が揃っています。
「Wayland Debug」の使い方は、以下を参照してください。