バグ検出ドリル(18)IoT時代だからこそ重要、単純でも検出が難しい通信系バグ:山浦恒央の“くみこみ”な話(118)(4/4 ページ)
バグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第18回の問題は、相互に通信する機器のソフトウェアのバグです。IoT時代を迎えて利用場面が増えている、通信系のバグを見つけ出しましょう!
4.今回の解答
今回の解答は、「クライアントとサーバ間の送受信データの構造体が異なる」です。
本問題では、音楽プレーヤーのクライアントとサーバがTCPで通信しています。両者のやりとりのデータは、ヘッダファイルに記載しているのですが、両者で順番が異なっています。
図2は、クライアントとサーバの送受信用の構造体をコメント抜きで抜粋したものです。見れば分かる通り、構造体メンバのidとpasswordの並び順が異なっています。そのため、両者で異なるデータを上書きしていました。結果、モードは正しく表示でき、残りは不正データとなりました。つまり、A君とB君の最大の失敗は、共通のヘッダファイルを使わず、別々に定義したことにあります。
「超初心者の単純なバグ」と思った方もいるかと思いますが、この類いのバグはたまに起こります。例えば、データの転記ミス、エンディアンや構造体のアライメントの違いなどから、正しいデータを送っているつもりでも意図している値を送受信できない場合があります。下記に詳細を示します。
(1)データの転記ミス
データの転記ミスですが、送受信するデータは何らからの開発ドキュメントに書いてあります。プログラマーがその記述を間違えて記載すると、想定外の値が現れます。
(2)エンディアンが異なる
エンディアンとは、バイト列の並び順のことです。本問題では、Intel系CPUですから、ビックエンディアンを使っています。場合によっては、相手はビックエンディアンでもう片方がリトルエンディアンの場合があるので注意が必要です。両者が違う場合は、値が反転して現れます。
(3)構造体のアライメントが異なる
構造体のアライメントとは、コンパイラが一定の間隔でデータを整列することです。例えば、構造体のメンバ変数に「char型変数」と「int型変数」の2つある状態でサイズを取得することを考えます。char型のサイズを1バイト、int型のサイズを4バイトとすると、「1バイト+4バイト=5バイト」となるように思いますが、実際は、「1バイト+3バイト+4バイト=8バイト」と3バイト詰め物をいれることがあります。何バイトの詰め物を入れるかは、コンパイラに依存しますので、結果として送受信側のデータサイズが異なることになります。
5.自己採点シート
今回の自己採点シートを以下に示します。
問題 | 内容 | 配点(点) |
---|---|---|
ネットワーク型音楽プレーヤープログラム | 問題を一通り読んだ | 20 |
クライアント側プログラムを一通り読んだ | 20 | |
サーバ側プログラムを一通り読んだ | 20 | |
バグの原因が、構造体の順番が異なっていることを見つけた | 40 | |
その他のバグを見つけた | +5 | |
リスト4 自己採点シート |
6.終わりに
近年のIT技術の発達により、複数の機器が相互に連動して動くソフトウェアが増えてきました。今回は、その一例としてTCPを題材とした問題を出題しました。たかだか構造体の順番の話でしたが、何らかの原因で意図したデータを送受信できないことがあります。その場合は、冷静に送受信側にログを入れておき、正しいデータが送れているかもう一度確認すると良いでしょう。また、両者の機器の違いを明確にしておくとバグの未然防止につながります。
余談ですが、今回のプログラムには、エラー処理はほとんど記述していませんが、通信系ソフトでは通信異常などのエラー処理も大切です。このプログラムを題材としてその他のバグを見つけると面白いと思います。
参考文献
「TCP/IPソケットプログラミング C言語編」(小高知宏(訳)、2003年、オーム社)
「Linuxシステムコール基本リファレンス──OSを知る突破口(WEB+DB PRESS plus)」(山森丈範、2018年、技術評論)
東海大学 大学院 組込み技術研究科 非常勤講師(工学博士)
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- ≫連載「山浦恒央の“くみこみ”な話」バックナンバー
- バグ検出ドリル(17)「よくある単純なバグ」だからこそ見つけにくい
バグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第17回の問題は、前回と同じ音楽プレーヤーのプログラムから出題します。「よくある単純なバグ」が潜んでいますが、見つけ出せますか? - バグ検出ドリル(16)音楽プレーヤーに潜むバグを見つけ出せ
バグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第16回の問題は「簡単なバグなのに、なかなか見つからない」バグです。何で見つからないんだ! - バグ検出ドリル(15)なぜ「山田三郎」が「まだまだ天田三郎」に化けるのか
バグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第15回の問題は、「思った通りに動いてくれないプログラム」のバグです。少しはプログラマーに忖度してくれよ! - バグ検出ドリル(14)タイポグリセミア現象もびっくり、恐るべきは思い込み
バグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第14回の問題は、前回に続いて「煮詰まったバグ」です。煮詰まっているがゆえに、バグの原因が分からなくなる事態に対処してください! - バグ検出ドリル(13)のたうち回る地獄、煮詰まったバグを解決せよ
バグは至るところに、しかも堂々と潜んでおり、自信満々なプログラマーほど、目の前のバグに気付かないものです。「バグ検出ドリル」の第13回の問題は、筆者の経験を基にして作った「煮詰まったバグ」です。プログラムが思い通りに動かず「のたうち回る地獄」のような状況に対処してください!