‹ Atlasの力を引き出す

Atlasの力を引き出す (3): ソフトウェア解析にAtlas Shellを活用する

Atlas ShellはAtlasのコマンドライン側であり、Smart Viewが適切なツールでないときにクエリとスクリプトを実行するためのものです。

Atlasは、ソフトウェア解析をできる限り対話的に行えるように設計されています。そのSmart Viewsは、ソフトウェアをその場で解析するための優れたグラフィカルインターフェースを提供します。しかし、解析者がスクリプトを実行できるコマンドラインインターフェースを望む場面もあります。その場合は、Atlas ShellがSmart Viewsの代わりになります。Atlas Shellは、開発者が自身のプロジェクトのグラフ表現をクエリし、解析し、可視化し、解析作業を効率化できる、用途の広いインターフェースです。

Atlas Shell: コマンドラインへの入り口

Atlas Shellは、Atlasがお使いのコードベースに対して作成するグラフ表現を扱うように設計されています。開発者は次のことができます。

  • プロパティに基づいてコード成果物を選択する。
  • ループや分岐などの成果物を数えるといった計算を実行する。
  • より深い洞察を得るために、結果を対話的に可視化する。
  • 解析作業を効率化する。

これを可能にしているのは、Atlasのクエリ言語です。クエリ言語は、Atlasのグラフデータベーススキーマに基づいています。詳細は、弊社のホワイトペーパー [1] に記載されています。

簡単な例で、Atlas Shellが動作するところを見てみましょう。

Atlas Shellの動作: 関数内の入れ子ループを見つける

Atlas Shellへの移動は簡単です。

Open Atlas Shell

  • Atlasメニューから Open Atlas Shell を選択します。
  • 通常は画面下部にドッキングされた、Atlas Shell というタイトルの新しいウィンドウが表示されます。都合に合わせて位置を変えることができます。

例として、与えられたコードの中から入れ子ループを見つける方法を示します。簡単にするため、関数を1つだけ含む図の例示コードを使います。同じ手順で、数十万個の関数を含むコードも容易に扱えます。

Eclipse上のdskqopt.cで入れ子のforループが強調表示され、dskqoptのAtlasグラフには外側のループヘッダーと内側のループヘッダー for (i < 512) が示されています。

入れ子ループを見つける: 関心があるのは、強調表示されたコード部分を検出することです。右側は、続くクエリの結果です。入れ子になった2つのループヘッダー(外側と内側)を捉えています。

次の一連のクエリは、与えられた関数の中の入れ子ループを捉えます。

var dskqopt = functions("dskqopt")
var dskqoptCFG = cfg(dskqopt)
var dskqoptLoops = dskqoptCFG.nodes(XCSG.Loop)
dskqoptLoops.eval.nodes.size   // = 3
var nestedLoops = universe.edges(XCSG.LoopChild).between(dskqoptLoops,
                                                         dskqoptLoops)
nestedLoops = nestedLoops.retainEdges
show(nestedLoops)

これらについて簡単に説明します。

  • 関心のあるコードを表す変数を作成します。この例で関心があるのは、dskqoptという1つの関数だけです。そのために functions() クエリを使いました。これをコードベース全体(universe())へ置き換えても、残りのクエリは一切変更する必要がありません。
  • 次に、dskqoptの制御フローグラフ(CFG)を計算します。CFGは、ループを含め、dskqopt内のすべてのプログラム文を捉えます。cfg() クエリは、そのためのものです。
  • Atlasは、ループヘッダーを表すプログラム文にXCSG.Loopというタグを付けます。.nodes() クエリでそれらを選択できます。3つあります。
  • ループの入れ子は、内側のループが外側のループの中に含まれるという二項関係です。Atlasは、この関係や、同様の多くの関係を、グラフのエッジとして表現します。この関係は、エッジ型XCSG.LoopChildで表されます。between() クエリを使うと、入れ子ループ(外側と内側の両方)を捉えられます。between() は走査クエリです。指定された種類のエッジだけを使い、指定された開始ノードと終了ノードの間をグラフ走査して、2つのノードの「間」にある部分グラフを捉えます。
  • 上のクエリで入れ子ループがない場合、走査するエッジがなく、非連結の部分グラフが残ります。関心があるのは入れ子ループだけなので、これらは取り除く必要があります。retainEdges() クエリが、まさにそれを行います。
  • 最後に、show() クエリを使うと、解析の結果を可視化できます。

これらのクエリは、プログラムとして定型化し、解析パイプラインの一部にすることができます。ループヘッダーだけでなくループ本体も計算するように、変更できます。これらのクエリの結果をテキストでエクスポートすることもできます。弊社では、Atlas Shellにできることすべての詳細を掘り下げる記事を、これからも書いていきます。続報にご注目ください。

Atlas Shellが際立つ理由

Atlas Shellは、コード解析を動的で直感的なプロセスに変えます。その力は、グラフデータベーススキーマに支えられた用途の広いクエリ言語に由来します。このクエリ言語をAtlasの可視化機能と組み合わせることで、開発者は次のことができます。

  • コード内の複雑な関係を容易にたどる。
  • 制御フローと依存関係への洞察を得る。
  • サイバーセキュリティや性能最適化などの領域へ、解析を広げる。
  • 自身のワークフローの中で解析作業を効率化する。

Atlas Shellは、Atlasが提供する強力なクエリ言語を引き出します。クエリし、計算し、可視化できるその能力は、大規模で入り組んだコードベースの解析に欠かせません。ですから、次に難しいソフトウェア解析の問題に直面したときは、Atlas Shellが味方です。

参考文献

[1] A Humane, Graph-Based Representation of Programs and Analyses、ホワイトペーパー: https://ensoftupdate.com/papers/XCSGWhitepaper.pdf

次へ: Atlasクエリを理解する

ご質問、または修正のご希望はありますか?

どのようなご用件ですか?