お待たせしました!
DT+TraceのPython対応記事、第2弾になります。

前回、Pythonとネイティブコードの同時プロファイリングの必要性とそのアプローチについて説明しました。
今回は、Python対応したDT+Traceのβ版を使って、実際にPythonとネイティブコードの同時プロファイリングする際の手順と動作イメージをご紹介したいと思います。

 

使用した各種環境

・Raspberry Pi

以前紹介させていただいたAUTOmeal(リンクはこちら!)など、社内社外の案件で頻繁に使用されているRaspberry Pi。それをふまえ、 PythonとCの同時動作を行うプラットフォームとして選択しました。

Pygame

近年Pythonを用いて簡単にゲーム開発ができるツールとして普及しており、またC言語のライブラリも豊富な事から、動作とデータの関連性の分かりやすさを重視して、グラフィカルなPythonプログラムを動作させる対象として使用しました。

・ctypes

Pythonが標準モジュールとして提供しているC/C++の共有ライブラリを呼び出すモジュールです。Python環境があればなにも追加することなく手軽にC言語のライブラリを呼び出すことができます。

・リモートデスクトップ

ゲームを動作させているRaspberry Pi側の状況とDT+Trace側の状況を合わせて表示・操作させるため、今回Raspberry Piはリモートデスクトップで動作させています。

 

トレースデータを取るための手順

実機動作における動作ログをDT+へ出力するため、まずソースコードにテストポイント処理(≒printfデバッグで使用するprint文に近いもの)を自動挿入します。この自動挿入におけるコードの解析にはDT+Builder(開発中)が使用されます。この工程を行ったソースコードを専用のドライバと併用することで、DT+に対して動作状況をリアルタイム出力する事ができます。

今回使用したPythonコードの一部にテストポイントの挿入を行うと、以下のように加工されます。

 1 # 車を描画
 2 def draw_car(self):
 3    DtTestPoint(0x00000010, 9)
 4    SCREEN.blit(self.image, [self.rect.x, self.rect.y])
 5    DtTestPoint(0x00000010, 10)
 6
 7 # x座標移動 – Playerの車の動きを制御
 8 def move_x(self):
 9    DtTestPoint(0x00000010, 11)
10    self.rect.x += self.dx
11    DtTestPoint(0x00000010, 12)
12 
13 # y座標移動 – Playerの車の動きを制御
14 def move_y(self):
15    DtTestPoint(0x00000010, 13)
16    self.rect.y += self.dy
17    DtTestPoint(0x00000010, 14)
18
19 # 画面の外へ移動できないようにする
20 def check_screen(self):
21    DtTestPoint(0x00000010, 15)
22    if self.rect.right > WINDOW_WIDTH or self.rect.x < 0:
23       DtTestPoint(0x00000010, 16)
24       self.rect.x -= self.dx
25    if self.rect.bottom > WINDOW_HEIGHT or self.rect.y < 0:
26       DtTestPoint(0x00000010, 17)
27       self.rect.y -= self.dy
28    DtTestPoint(0x00000010, 18)
29
30 # 車両の衝突検出
31 # distance : 右左上下の間隔設定
32 def check_collision(self, car, distance = 0):
33    DtTestPoint(0x00000010, 19)
34    if (self.rect.top + distance < car.rect.bottom) and (car.rect.top < self.rect.bottom – distance) and (self.rect.left + distance <car.rect.right) and (car.rect.left < self.rect.right – distance):
35       DtTestPoint(0x00000010, 20)
36       return True
37    else:
38       DtTestPoint(0x00000010, 21)
39       return False
40    DtTestPoint(0x00000010, 22)

赤文字の部分に、テストポイントが挿入されているのが分かりますでしょうか?
こうして準備がされた各ソースは、以下のようにデータをやりとりします。

ctypesは、ビルドされたライブラリファイル(.dll,.so等)を読み込み、Pythonで扱えるよう橋渡しをしてくれます。
今回ターゲットとしたPythonプログラム(Pygameで作られたレースゲーム)においても、以下のように読み込みました。

 1 from DtTestPointDriver import DtTestPoint
 2 from ctypes import *
 3 import pygame
 4 import random
 5 #レースゲーム用DLL
 6 cardll = cdll.LoadLibrary(“./carlib/carlib.so”)
—————-省略——————-
 7     #座標更新処理
 8     cardll.PositionUpDate(player.rect.x, player.rect.y)

上記では、PositionUpDate()がライブラリ内の関数になります。
このように、非常に簡単な編集だけでPythonはctypesを介してC言語の関数を呼び出し、同時に動作させることができます。

こうして、DT+Traceでデータを収集する準備ができました。

 

動作確認


それでは早速動作させてみましょう。
Pythonプログラム(レースゲーム)を起動、計測を行います。

動きました!
レースゲームの動作データがDT+で取得/記録されている事が確認できます。

 

最後に

さて、今回はPythonとC++の同時プロファイリングと言う事で、
開発中のDT+Trace次期バージョンと、その追加アプリケーションDT+Builderを使用した、導入・実施例を見ていただきました。

Pythonの特性から、メンテナンスを考慮した置き換えを行う事例はこれからも加速していく事でしょう。
そのような中で、ただメンテナンスを行うだけでなく、
そのメンテナンス結果が正しいことを検証していく機会も加速していきます。
新しい「DT+Trace」が、その流れの中で開発者の方々の助力になれば幸いです。

今回ご紹介した機能は、2022年5月現在開発中のものとなります。
リリース時の実際の仕様とは異なる場合がございますので、予めご了承ください。
なお、ご不明な点につきましては、弊社サポートチームまでお問い合わせください。
お問い合わせはこちら

動的テストの事例紹介ウェビナーやります!

組込み機器開発特有のソフトウェアデバッグ、テストにお困りではありませんか?
初期化処理や処理時間、複数CPUのシーケンス処理など、どのようにテストしていますか?
複数の機器で構成されたシステムでは、
「機器同士のやりとりを把握することができない」
「デバッガを使ってブレークをかけることができない」
といった問題にぶつかり、ソフトウェア内部の動きを把握することは困難です。
そこで今回は、動的テストツールDT+ユーザー様を講師にお迎えし、
このような課題に対する活用事例をご紹介させていただきます。
ぜひお気軽にご参加ください!

お申込みはこちら!