Linaro DDT

直観的で使いやすい C/C++、Fortran 向けデバッガー

評価版を申し込むLinaro DDT を購入


C/C++、Fortran 90 のマルチスレッド/並列コード向けデバッガー

プログラミングの 50% はデバッグに費やされていると言われています。本製品は、このデバッグに掛る時間を大幅に短縮します。デバッグに多くのコストが掛っている企業は、問題を素早く解決するために Linaro DDT を利用することをお勧めします。

Linux で動作する C/C++、Fortran 90 アプリケーション向けのデバッガーである Linaro DDT は、より効率的な開発を支援します。マルチスレッド/マルチプロセスのアプリケーションのデバッグが可能であり、複雑に関連しているコンポーネント間のデバッグを容易にします。


本製品は、開発ツールスイートである Linaro Forge に含まれています。


初心者にも熟練者にも使いやすく設計されたデバッガー

ますます並列化が進んでいくプロセッサー、クラスター、スーパーコンピューターを活用するために開発されたソフトウェアのデバッグは複雑になりがちです。本製品の強力で直観的な GUI や配列を可視化する機能などにより、複雑なデバッグは単純化されます。

コマンドラインを利用する熟練者向けに、自動変数比較機能やインプロセスのメモリ デバッグ機能は単一のコマンドで利用可能です。事後分析に役立つように、リッチテキスト形式/テキスト形式でのログ ファイルも生成されます。


生産性を維持するクロスプラットフォーム

新しいアーキテクチャやシステムに移行する際に、新たなツールの利用方法を学ぶ必要が無いことは大きなメリットです。Linaro DDT はあらゆる環境、ノートパソコン、最新のスーパーコンピューター、次世代のアーキテクチャで動作します。Arm、NVIDIA CUDA、IBM BlueGene/Q、OpenPOWER をサポートします。


デバッガーの機能および特長

Linaro DDT は、開発者のデバッグにかかる時間を短縮し、ソフトウェアのタイムリーな完成を支援します。この包括的な C/C++、Fortran、Fortran 90 向けのマルチプロセス/マルチスレッド アプリケーション用デバッガーを使うことにより、次のことが実現できます:

  • MPI を使った HPC クラスターなど 、複数のサーバーで起動するネイティブ Linux* アプリケーションのデバッグ
  • プロセスおよびスレッドの管理 – プログラムのステップ実行、変数の変更やエラー、あるいはユーザーが追加したブレーク ポイントでのプログラム停止
  • 市場をリードするメモリ デバッグで、メモリ リーク、ダングリング ポインター、境界を超えた配列アクセスなどに起因する見つけ難い問題や断続的な問題を検出
  • 強力で拡張可能な C++ STL デバッグで STL コンテナを直観的に表示
  • マルチプロセスの変数および配列を表示し、自動的に変更を検出
  • ビルトインの編集、ビルド、バージョン管理機能の統合 – リモート システムでの開発を強力にサポート
  • オフライン モードでの非インタラクティブ モードのデバッグおよびアプリケーションの動作や状態のレコーディング

強力でスケーラブルなマルチプロセス/マルチスレッドのデバッグ

MPI や OpenMP* などのライブラリを使用したマルチプロセスやマルチスレッドの開発する場合、Linaro DDT を使うことで並列処理の実装が容易になります。

スレッドやプロセスを個別に、かつ一括して管理

  • MPI プロセスのグループや、すべてのまたは個々のスレッド (OpenMP*/pthreads) にブレーク ポイントを設定
  • プロセスやスレッドを個別にまたは一括してステップ実行/再生
  • 変数値および式の値、現在のコードの位置やプロセスの状態に基づいてプロセス グループを作成

DDT は、優れたデータ収集機能や差異のハイライト表示機能によってプログラムの状態を自動的に比較できるため、複数のコンテキストをすばやく処理できます。

並列スタック ビューにより、少数のものから数百、数千にいたるスレッドおよびプロセスのスタックをスケーラブルに表示できます。スタックをグループ化し、ダイバージェンスを示唆する差異をハイライトするため、MPI や OpenMP*、pthreads、CUDA および OpenACC などのデバッグに最適です。

優れたハイライトおよびスパークライン機能で各プロセスにおける変数値をサムネイル表示するため、通常と異なるデータの値やデータの変更を瞬時に確認できます。スパークラインに関する詳細は、ブログを参照してください。さらに、プロセスやスレッド間の比較ツールにより、データのグループ化や検索が容易になります。

DDT では、広く普及している MPI 規格のメッセージ キューをデバッグし、マルチプロセスのコードにありがちなタイプのバグを見極める役に立ちます。

  • グラフィックと表ベースのメッセージ キューの表示による、デッドロックやライブロック、メッセージの同期エラーなどといった問題の診断
  • オープンソース MPI の正当性チェック ツールとの統合サポート

Linaro DDT は、実証済みの非常に高速なパフォーマンスで、700,000 のプロセスを瞬時にステップ実行し、表示します。


データ調査

Linaro DDT を使うと、変数を表示して複雑なデータ構造体を把握するという必要不可欠な作業が容易になります。

  • 変更の自動検出機能により、デバッグ中に変数や式に変更が施されるのを表示
  • 変数、オブジェクト、モジュール、complex C++ クラス、構造体、Fortran 90 の派生型データ構造体および多次元配列などを参照
  • ポインターの逆参照およびオブジェクトのアドレス検索の後、メモリ デバッグでポインターの割り当て場所やサイズを確認
  • list や set、map、multimap、QString を含む、C++ や C++11 STL、Boost、Qt コンテナーなどの複雑なデータ構造体をスマートに表示
  • カスタム データ型を追加して必要なデータのみを表示
  • ウォッチ ポイントを設定して、プロセスによるデータの読み込みまたは書き出し時にプログラムを停止

C++、Fortan 関連の機能については、C++ debuggingFortran debugging ページを参照してください。


メモリ デバッグ

DDT の組み込みメモリ デバッガーは、ヒープ メモリの使用における問題を自動的に表示します。

  • 例外やクラッシュ発生時に即停止 – 使いやすく、包括的なインターフェースでクラッシュの原因であるソースやデータを特定
  • 境界を超えたデータ アクセスを発生後即時にキャッチ
  • メモリ リーク (memory leaks) はもう起こさせない: メモリ割り当てに関わるソースの場所をリーク レポートに表示
  • カスタム アロケーターのサポートにより、アプリケーションの必要に応じたレベルで割り当て場所をレポート
  • ダングリング ポインターをチェック (dangling pointers)
  • ポインターの有効性、割り当て場所および割り当てサイズのスタック全体を表示
  • malloc、new、その他の関数で C/C++ メモリを割り当て
  • Fortran/Fortran 90 の割り当て可能なメモリおよびポインター

詳細は、メモリ デバッグ ページを参照ください。


強力なナビゲーション、エディット、ビルドおよびバージョン管理

デバッグに成功すると、コードの高速化が期待されます。Linaro DDT は、開発ツール スイートである Linaro Forge の一部です。DDT は単一ツールとして、または Linux* 上での並列/マルチスレッド コードの代表的なプロファイラーである Linaro MAP (Linux parallel and threaded code profiler、 Linaro MAP) を含む Linaro Forge ライセンスの一部としても入手可能です。MAP は、DDT と同じユーザー インターフェースおよびインストールを使用しているため、デバッグ後簡単にコードのプロファイルへ移行できます。

開発者は、パワフルなユーザー インターフェースでデバッグ作業と同時に編集、ビルド、そしてコミットすることができます。

リモート システムを使用する場合でも、Mac や Windows®、Linux* クライアントのノートパソコンからリモート クライアントを使って問題なく接続できます。


バグ修正へのスマートなアプローチ

Linaro DDT はベスト プラクティスを統合し、デバッグに費やす時間を削減し、より迅速に問題の原因を明らかにします。

  • C/C++ および Fortran 用の静的解析でいち早くバグを検出し、ありがちなエラーをソースで取得可能
  • なぜ現在のコードは以前のコードと動作が異なるのか?バージョン管理機能との統合により、コードの変更箇所をハイライトし、なぜ、どこで変更が生じたのかを確認可能
  • 各コードの変更箇所におけるすべてのプロセスの変数値を 1 つのコマンドで自動的にログでき、特定の変更がなぜ、どのようにして問題となったのかを正確に追跡可能

Linaro DDT のログ ブックには作業中に踏んだステップがすべて記録されるため、デバッグの進捗管理も簡単です。

  • 過去に見落としていた問題を容易に再確認できる常時自動記録のデバッグ ログ
  • チーム メンバーとログ ブックを共有し、共同デバッグを実現
  • 2 つのトレースを対照比較し、システム、バージョン、およびプロセス数の間における変更を確認

スケーラブルな printf および強力なコマンドライン モード

トレース ポイントを使うことで、スケーラブルな printf デバッグが実現します。DDT では、コードにトレース ポイントを挿入し、コード 1 行ごとにその値をログします。結果は、対話的にまたはオフライン デバッグ モードで利用可能です。

オフライン モードでは、スリープ中でもデバッグできます。バッチ スケジューラーを利用してコマンドラインからオフライン デバッグの実行をスケジュールすると、ジョブの完了時に DDT からテキストまたは HTML 形式のエラーおよびトレース レポートが送信されます。オフライン デバッグに関する詳細は、ブログを参照してください。


膨大なデータセットの処理及び視覚化

DDT は、科学計算および技術計算における膨大なデータセットの処理を実現できるように設計されています。複数のプロセスに分散している場合でも、巨大な配列の表示またはフィルタリングができます。

  • 業界標準のデータ形式である HDF5 および CSV へエクスポート
  • すべてのプロセスを並列参照し、パワフルなフィルタリング機能でペタバイト単位のデータを並列検索して統計データを収集
  • Linaro DDT のコネクターで視覚化ツール VisIt (VisIt scientific visualization tool) に接続し、データを視覚化して同時にデバッグ

これからの HPC アーキテクチャに向けたクロスプラットフォーム

Linaro DDT はクロスプラットフォームに対応しており、現在使われている主要な技術計算プラットフォームをすべてサポートしています。1 つの製品で CUDA デバッグ (CUDA debugger)、並列デバッグ、マルチスレッド デバッグ、OpenMP* プログラムのデバッグおよびメモリ デバッグ (memory debugger) 機能のすべてを備えており、ハイブリッド型のプログラミング モデルをサポートしています。


メモリ デバッグ

Linaro DDT のメモリ デバッガーは、Linux* 上での C/C++、および Fortran コードにありがちな多くのメモリ エラーの修正を支援します。このモードの機能は、コマンドライン デバッガーや print 文によるデバッグよりもはるかに優れています。

メモリ デバッグは、DDT のチェック ボックスをオンにするか、コマンドラインに "--mem-debug" を追加することで有効になります (Cray XC もしくは XK プラットフォームに関しては、リンクするためのさらなるステップが必要となります)。

Linaro DDT を使うことにより、次のような課題の答えを見つけ、問題を解決することができます:

  • どの程度メモリを消費しているか
  • 最もメモリが割り当てられているコードはどこか
  • メモリ リークは存在するか、どこでメモリの解放を失敗しているか
  • 解放後のポインターが利用され、アプリケーションのクラッシュの原因になっているか
  • ポインターはまだ有効なのか、どこにどの程度のメモリが割り当てられているのか
  • アプリケーションが無効なポインターを正しく解放しているか
  • 範囲外の領域のメモリを読み書きしていないか

これらの課題の答えを見つけることで、予期せぬクラッシュを防ぐことができます。ここに挙げられた課題を解決することは、ソフトウェアの品質改善にもつながります。


ヒープ

メモリ デバッグ モードによって検知されるメモリの領域をヒープといいます。ヒープとは、C では malloc、free、その他類似の関数、C++ では new/delete オペレーター、Fortran 90 あるいはそれ以降の Fortran 派生言語においては allocate/deallocate などのプリミティブ型によって管理されている領域を指します。

DDT は、これらの関数をインターセプトしてエラーを検出し、情報を記録し、またメモリがどれだけ使用されているかを測定します。

チェックのレベルは、メモリ デバッグの設定ダイアログにある設定レベルでベーシック モードからフル モードに調節できます。フル モードでは、割り当て数の多いコードのスピードを下げる可能性がありますが、ベーシック モードでは時間的なコストはほとんどありません。


メモリ使用量

メモリの総使用量に注目することは重要です。メモリを過度に割り当てた結果、プロセスがオペレーティング システムに強制終了されてしまうことも考えられます。

プロセスのメモリ使用量は、[Tools (ツール)] > [Overall Memory Stats (全体のメモリ統計)] メニューで表示できます。 複数のプロセスをデバッグする場合には、それぞれのプロセス (または使用度の高いプロセス群) は、右のように表示されます。

この表示画面は、メモリ デバッグ機能が有効化されている場合に利用できます。総使用量が上昇した場合には、メモリ リークが示唆されます。

DDT を含むツール スイート、Linaro Forge にも、パフォーマンス プロファイラーである MAP の機能としてメモリ プロファイリングが存在します。MAP では、メモリの使用状況が変化する様子がグラフィック表示されますので、いつどこでメモリの使用量が増加したのかを絞り込むことができます。


メモリ リークの検出

メモリが割り当てられた後に解放されなければ、結果的にメモリ不足の問題が生じ、突然プログラムが終了してしまいます。

メモリ リークは、メモリ デバッグが有効化されている場合、[Tools (ツール)] > [Current Memory Usage (現在のメモリ使用量)] メニューで検出できます。

割り当てられたメモリに対し、DDT は個別にスタック トレースおよび指定した割り当てサイズを記録します。これにより、コードのどこで割り当てがなされ、どれだけのメモリを使用しているかが確認できます。

[Current Memory Usage] ダイアログはこの情報を使い、使用バイト数を単位とした呼び出しの先頭の位置をグラフに描画します。リークが起こった場合には、この棒グラフにはっきりと表示されます。棒グラフの要素をクリックするとポインターがリストアップされ、さらにその中からポインターを選択すると、その割り当てのスタックとサイズが表示されます。

カスタム アロケーターとクラス コンストラクター

多くのコードは少数のエントリー ポイントを介して割り当てを行っています。

たとえば、メモリの割り当てには C++ クラスのコンストラクターがよく使用されます。プログラム中を通して、最も有用なクラスが呼び出されます。この場合、コンストラクターを呼び出したコード行によって割り当てをグループ化すると、コンストラクターの呼び出しが不定形な塊としてひとまとめにされないためより有益です。

コンストラクターの呼び出しごとにグループ化するには、棒グラフのブロックを右クリックし、その関数を “Custom Allocator (カスタム アロケーター)” として追加します。その関数の呼び出しは、呼び出し位置によって個別にグループ化されます。

リーク検出の自動化と回帰テスト

DDT には、上記で説明した [Current Memory Usage] ツールの対話型情報に類似した、非インタラクティブ型のメモリ デバッグ モードがあります。このモードは、メモリの使用量を測定し、リークが実動コードに入り込まないことを自動的に保証するため、夜間テスト中や CI サーバーなどでよく使われます。

このモードでは、プロセスの終了後にも残されたままとなっているメモリの割り当て情報が記載された HTML ファイルが作成されます。

ddt --offline offline-log.html --mem-debug ... application.exe ....

これにより、プログラムの実行中にログされた重大なデバッグ イベントやリーク レポートを含む、非インタラクティブ モードにおけるデバッグ セッションの注釈付きログ ファイルが作成されます。


無効なポインターの解放

すでに解放されている割り当てや、割り当てられていない、または正規のヒープ領域に到達していない偽のアドレスを解放しようとする時にもクラッシュが起こる場合があります。

結果として即時終了、ヒープ コラプション、あるいは将来的なクラッシュにつながります。

DDT では、無効なポインターが検出されると即エラーメッセージがトリガーされ、エラーの起こった正確な場所でプロセスを停止するので、このような問題を回避することができます。


ダングリング ポインター

ダングリング ポインターとは、解放されたものの null に設定されていないメモリのポインターのことを指します。あとに続くコードがダングリング ポインターを使い続けると、データはまるで有効に見えますが、ある時突如としてメモリが別の場所に再割り当てされてしまう可能性があります。

ダングリング ポインターは、予期できない動作、サイレント データ コラプション、またはプログラムのクラッシュを引き起こす原因となります。

ダングリング ポインターの検出機能を有効にするには、メモリ デバッグが Fast よりも 1 つ上のレベルに設定されている必要があります。[Enabled Checks] ウィンドウに “free-protect” という言葉が表示されます。

ダングリング ポインターの問題を検出するには、通常はこのレベルのメモリ デバッグで十分だと考えられます。ダングリング ポインターが再使用されると、再利用したコードで正確にプログラムが停止し、次のようなエラー メッセージが表示されます:

デバッガーでは、どのポインターがダングリングしていて、もともとそれがどこで割り当てられたのかも表示されます。いずれかのポインターまたは動的に割り当てられた配列を右クリックし、メニューから [View Pointer Details (ポインターの詳細情報を表示)] を選択します:

Linaro DDT では、どの特定のポインターがダングリングしているかが直ちにわかり (ポインターがすでに解放された割り当てを指していることを示します)、その割り当てに起因する関数呼び出しのフルスタックを表示します。


ポインター情報の確認

上のダングリング ポインターのセクションで説明したとおり、[Pointer Details] ウィンドウにはポインターに関する詳細情報が表示されます:

  • ポインターの有効性、割り当てやダングリングの有無
  • 割り当てサイズ
  • のちに解放されたダングリング ポインターを含む、ポインターの割り当てられたコード内の正確な場所およびスタック
  • 実際にダングリング ポインターである場合、ポインターが再度解放されたコード内の正確な場所およびスタック

特に上の画像では、ポインターが hello.c:88 で割り当てられたということが確認でき、そこをクリックすることで直ちにソース コード ビューアー内でその場所に移動できます。

このメモリがどこで解放されたのかを知ることもできます。


配列範囲外またはメモリの割り当て範囲外への読み取り/書き込み

配列範囲外またはその他のメモリの割り当て範囲外で値を読み取ることは、好ましいことではありません。

大半の場合には見過ごされ、問題が発生しないこともありますが、ランタイム環境でのごく僅かな変更がクラッシュの有無を左右し、断続的なクラッシュを引き起こす可能性もあります。

  • 割り当て範囲外の値を読み取ることで、戻り値またはコード パスが信頼性の低く不確かな要素に依存してしまうため、計算に誤差が生じる原因となります。
  • 割り当て範囲外での書き込みは、書き込みを行ったことにより破損してしまったこの場所を再利用する別のコードで不確かな動作を引き起こす可能性があります。
  • アドレスがプログラムの割り当てページ以外の場所にある場合、読み取りも書き込みもクラッシュの原因になり得ます(通常は 4096 バイトですが、システムによってはさらに大きなページを使用しています)。

DDT では、このようなエラーを回避できます。オペレーティング システムに働きかけて各割り当ての前後にページを作成し、それぞれを読み取り/書き込み禁止にします。保護されているメモリに読み取りまたは書き込み操作が行われようとすると、Linux* オペレーティング システムがデバッガーに通知します。これらのページは "ガード ページ" または "レッド ゾーン" として知られています。

大半の科学計算を行うコードや Fortran 90 コードなど、大きな割り当ての比較的少ないコードに関しては、ガード ページとして使われるページ数も少なくなります。

C++ コードは、概して小さい割り当てを大量に使用しますので、プロセス リミットに到達してしまう可能性があります。そのようなコードに関しては、DDT では、“フェンス チェッキング” または “フェンス ペインティング” として知られる 代替設定を提供しています。この設定では、割り当てメモリの上下数バイトを定期的に検証し、予期しない書き込みがされていないかを確認します。このモードがチェックするのは書き込みだけで、誤った読み取りは検出できないため、可能な限りガード ページ モードの方が優先的に使用されています。

 

ライセンス体系、価格、お見積り依頼、ご購入前の技術的なお問い合わせなど、本製品に関するご質問、ご不明な点はお気軽にお問い合わせください。

お問い合わせ

 

ページトップへ