アーケードゲームを支えるデバッグ術

ブログ読者のみなさん、はじめまして。
株式会社セガのベテランプログラマー阿部です。

このエントリーではデバッグ手法のあれこれについての体験談と、デバッグをテーマに一昨年に実施されたプログラマー向け新人研修の概要をお伝えしたいと思います。

EXE ファイルのデバッグ

同僚が作った EXE ファイルが手元にあり、あなたはこれを Windows で起動しようとしています。
起動してみたところ何も反応がなく、しかもそれは想定外のことでした。
「何コレ、動かないんだけど」とあなたが同僚に文句を伝えると、同僚はあなたに返します。
「こっちでは動いてるよ」

 

困りましたね。
あなたの手元には EXE のソースコードも無ければ、Visual Studio もありません。
こんな時、どうするのが正解でしょうか?

実はこんな状況でもやれる事がいくつかあるんです。
わたしなら プロセスのメモリダンプ を取って、同僚に渡します。

 


プロセスダンプがあれば、同僚はプログラムがどこまで進んだのかを Visual Studio で把握することができるようになるのです。
プロセスダンプの取得は ツール不要で Windows デスクトップから操作可能 なので、この方法は一番気軽に試せることでしょう。

 

f:id:sgtech:20201124210821p:plain

プロセスダンプの取得

あるいはその前に Sysinternals Suite に含まれる DebugView の出力を確認してみると、プログラムに埋め込まれた OutputDebugString() から 何らかの手掛かりが得られるかもしれません。
もし EXE ファイルと PDB ファイルが揃っていて 別の PC 開発環境があるなら、イーサネット経由でリモートデバッガをアタッチしても良いでしょう。
PDB ファイルが無いとしても 仮に EXE が .NET アセンブリなのであれば、ILSpy などの逆アセンブラーが使えるかもしれません。

 

こういう知識は「持っているかどうか」がとても重要 で、仕事の速いプログラマーほど よりたくさんの手段を自然と身に着けているような気がしています。
社内には SYS ファイル(デバイスドライバー)をデバッグできるプログラマーとかもいて、もうリスペクトしかないです。

イーサネット絡みのデバッグ

ネットワーク上のゲームサーバーと通信するクライアントプログラムを書いて、これをアーケードゲーム機で起動させたとします。
ゲームサーバーとの通信が「たまに成功しないことがある」という場合は、どうデバッグしたら良いのでしようか?

近年のアーケードゲーム機は PC アーキテクチャーをベースに設計されることも多く、セガでも Windows を搭載した機種が多数リリースされています。
コピーガードやリバースエンジニアリング防止を目的として、多くのアーケードゲーム機ではデスクトップ画面を開くことはできず、ネットワーク経由でのログインやプロセスへのアタッチもできません(外界からは ロックダウン されています)。

 

「たまに失敗」という場合は、ソースコードレビューで判明するバグがあるとは考えにくいです。
そこでわたしなら、 イーサネットを流れるイーサフレームを Wireshark でパケットキャプチャーする ことから始めてみます。

 

f:id:sgtech:20201124210834p:plain

フレームの測定


イーサネットを観測することで、最初にまず以下を見極められると期待しています。

  • ケース1: 想定通りにパケットが流れていない(送信失敗)
  • ケース2: 想定外のパケットが流れている
  • ケース3: 想定通りのパケットが流れている(送信成功)

その結果、クライアントのコードが悪いのか、OS 側スタックのネットワーク設定が悪いのか、上流のネットワークが悪いのかを絞り込める、という算段です。

 

f:id:sgtech:20201124210838p:plain

問題を切り分ける


なお 「上流のネットワークが悪い」という結果だった場合は、キャプチャーの測定範囲を変更して 問題の機器を特定 していきます。
過去には、全国ゲームセンターにあるルーターが原因ということもありました。

ルーターが IP パケットのチェックサムを再計算するときに、特定条件下で計算ミスが起こるため、
ルーターのさらに上位にあるネットワーク機器でパケットがドロップされていた

というもので、本来ならばルーターファームウェアを修正し更新版を配信することになります。

 

通信エラーだけではありません。
TCP 通信において 「スループットが足りない」という場合、ここでもパケットキャプチャーから始めるのは良い選択の1つ です。
測定結果から、次に挙げるような点検箇所がいくつか見つかることでしょう。

  • SYN パケットに時間が掛かっている
    → コネクションプールを導入するか、セッションクローズしないプロトコルを採用する
  • リクエストからレスポンスまでの間隔が圧倒的に長い
    → サーバー処理でスワップアウトやスロークエリが発生していないか確認する

周辺機器絡みのデバッグ

広く使われている キャラクター表示器 は、シリアルポートから送信されたアスキー文字や SJIS をドットマトリクスとして表示してくれます。

 

f:id:sgtech:20201124210830p:plain

キャラクター表示器(VFD)

ある日「キャラクター表示器の表示がおかしい」という報告をもらって現地確認に行くと、見慣れない文字列が確かに表示されていました。
プログラムから制御しているというのに、 プログラム内に存在しない文字列が表示されてしまうのはおかしい ですね。
この表示器を含めて、多くは RS232C という低速でレガシーなシリアルポートを使って接続しています。
RS232C 通信は物理層での冗長性に乏しいため、ひょっとすると外的要因でポートに電気的なノイズが乗ってしまい、パケットが化けてしまったのかもしれません。

 

ということで早速 RS232C を測定しました。
RS232C の測定には ロジックアナライザーという測定機器を使います 。
RS232C 接続を構成するラインをプローブすれば、各ラインの Hi/Lo をタイミングチャートとして確認できるようになります。

 

f:id:sgtech:20201124210826p:plain

研修で使用した ZEROPLUS 製 ロジックアナライザー

f:id:sgtech:20201124210842p:plain

測定結果のタイミングチャート

実際測定してみると、タイミングチャート上はプログラムからの出力がそのまま反映されており、異常な部分は見つかりませんでした(結局その後の調査で 別の原因が見付かりました)。

 

同じ手法は USB 機器にも使えます。
USB 機器の場合は USB 対応のプロトコルアナライザーを導入することもできます(実は USBPcap + Wireshark という別の選択肢もあります)。

ゲームセンターに設置されるアーケードゲームは、ゲームパッドに縛られない、多彩なユーザーインターフェースが特徴の1つになっています。
さらにユーザーインターフェースだけでなく、キャビネット上の電飾や可動部のモーターなど さまざまな周辺機器がつながっており、それらをすべてプログラムで制御しています。
そういった周辺機器としては、既製品を採用することもあれば、新規に設計することもあります。
ここにもデバッグの機会が大いにあります。

デバッグスキルブートキャンプ

ここまでいくつか紹介したように、「プログラムのデバッグに使えるもの」にはツール(ソフトウェア)だけでなく、測定機器(ハードウェア)も重要な一端を担っていることが理解いただけたかと思います。
また大学や専門学校などで 「プログラミングをマスターする機会」はあっても、「デバッグをマスターする機会」は無いのが実情 です。

わたしが所属する技術本部では、これらの背景を踏まえてプログラマー向け新人研修が実施されました。
デバッグスキルにフォーカスしたハンズオン研修、題して「デバッグスキルブートキャンプ」です。

学生時代に触れる機会が少ないであろう測定機器にも触れながら バグを正しく観測する技術 を習得し、 printf デバッグ だけでは決して成し得ない、バグの根本原因に辿り着く 貴重な体験を重視としたカリキュラム になっています。

 

開催形態は以下の通り。
他の新人研修とは異なり、新人プログラマーが実務に少し馴染んだ年末年始に開催されています。

  • ハンズオン重視: 当日フラっとやってきて学べればよい
  • 予習・宿題は原則ナシ: 「座学 20min、ハンズオン 75min」とか「座学 10min、ハンズオン 45min」とか
  • 開催時期はプロジェクト配属後6か月後から
  • 開催ペースは毎週1回、計9回(9ネタ)ほど

 

本来なら社内に広く展開して必修化した方が社員みんなの為になるのですが、測定機材の都合もあって一部組織内での開催にとどまっているのが現状のようです。
各回資料は社内公開されていますが、そのうち一冊の本に体系化されたらイイなと密かに期待しています。


f:id:sgtech:20201124210850j:plainf:id:sgtech:20201124210854j:plain

f:id:sgtech:20201124210845j:plain

 

黒子に徹する、裏方系エンジニア

デバッグの世界とデバッグスキルブートキャンプについて紹介しました。
最後にわたしが所属する技術本部について紹介します。

技術本部にはいろいろなキャリアの開発者が在籍しており、 ゲーム体験・感動体験を下支えする何か を日々開発しています。
わたし自身を例に挙げると 以下のような感じです。

  • ゲームを開発するためのライブラリを作ったり
  • コンバーターとか自動化ツールを作ったり
  • Windows Embedded を使いこなして、アーケードゲーム機向けの OS をビルドしたり
  • 開発者向けグループウェアを管理したり

近隣のデスクには ちょっと違う種類の仕事をしている人がいますね。

  • データベースとか VM をいじる人
  • 基板回路を設計する人
  • Maya 上のメッシュモデルをあれこれする人
  • ルーターとか「目新しいユーザーインターフェースデバイス」をいじめる人(w)など

千人規模の社内開発者を支える技術本部にはいろいろな仕事があって、それぞれに奥が深そうです。
そして ゲーム自体のおもしろさを追求するのとは違った立ち位置で、ゲーム周辺にある様々な問題を解決 しています。

 

わたしもゲーム開発を後押しする裏方系エンジニアに転身したことで、結果的にはいろいろなテクノロジースキルを身に着けることができました。
「開発したゲームで世界をあっと言わせる!」という部分に自信を持てなくても、「技術のことなら何でも任せて!」という自信に満ちたプログラマー/ソフトウェアエンジニアなら、セガでキャリアを積むのも悪くないと思いますよ。

ということで、現場で成長をつづけながら「縁の下の力持ち」として共に働ける仲間を求めています。

 

recruit.sega.jp


-----

©SEGA
記載されている会社名、製品名は、各社の登録商標または商標です。

 

Powered by はてなブログ