ソフトウェア設計及び演習2017

統合テスト

全体を繋げよう

個々のモジュールが完成したら,全体をリンクしてみましょう.

  • ソースプログラムと単体テストだけでは見つからなかったミスを発見できます.
  • 未完成な部品でも,リンクだけはできるようにプログラミングしてください.
  • インタフェースの思い違いが出てくるかもしれません.

リンクできるようになったらテストランしてみましょう.

  • 全体を通して実行できるようにしましょう.
  • 部品を完成させるのが難しい場合,取り合えず版でも良いのでまずは組み込んでみましょう.
  • あるいは,総合テストを作ってみましょう.

リンク時のエラー例

関数や変数の未定義,多重定義などのエラーの例がrepos:devel/ld-errorsにあります.

cd 適切なディレクトリ
svn export https://svn.cis.iwate-u.ac.jp/svn/csd/devel/ld-errors 
cd ld-errors
make

リンク時にエラーが起こりますので,確認してみましょう.

リンクとは?

  • コンパイルが通ったオブジェクトプログラムを集め,
  • 必要なライブラリ中の関数を集めて,
  • 実行可能なプログラムにする
オブジェクトファイル( .o ファイル)中の基本情報
  • 変数
    • 名前,サイズ,初期値
  • 関数
    • 名前,サイズ,関数の中身

型やパラメータの個数チェックはコンパイル時に行われ,リンク時には行われないので注意.

  • コンパイル時は,.h と .c に書かれていることに従い,その整合性を検査する
  • コンパイル時は,.c 間の整合性は検査できない
    • 例えば別々の .c ファイルに同名関数があったとしても,とりあえずは .o が作られる
  • リンク時は,.o 間の変数と関数の参照定義を行う.
    • 複数あるとか,
    • 定義されていないとか,
    • 大きさが違うとか,(異なる .h をつかってオブジェクトを作った場合など)

サンプルプログラム

  • common.h - 外部変数 xの宣言,関数 foo, goo の API を記述
extern int x;

int foo(int);
int goo(int);
# include <stdio.h>
# include <stdlib.h>

# include "common.h"

int x=0;

int main()
{
  foo(1); goo(1);
  return 1;
}
# include "common.h"

int foo(int y)
{
  return 1;
}
# include "common.h"

int goo(int y)
{
  return x;
}

サンプルプログラムでのエラーメッセージ

normal-link: 正常な場合

 % make normal-link
 cc -o exe main.o foo.o goo.o

undef-x-link: main.c で変数 x の定義をしなかった場合

 % make undef-x-link
 cc -o exe main-nox.o foo.o goo.o 
 goo.o(.text+0x4): In function `goo':
 : undefined reference to `x'
 collect2: ld はステータス 1 で終了しました
 make: *** [undef-x-link] エラー 1

undef-foo-link: foo.o をリンクしなかった場合

 % make undef-foo-link
 cc -o exe main.o goo.o 
 main.o(.text+0x16): In function `main':
 : undefined reference to `foo'
 collect2: ld はステータス 1 で終了しました
 make: *** [undef-foo-link] エラー 1

multi-x-link: 変数 x の多重定義(main.c, foo-x.c で x の初期値を定義)

 % make multi-x-link
 cc -o exe main.o foo-x.o goo.o
 foo-x.o(.data+0x0): multiple definition of `x'
 main.o(.bss+0x0): first defined here
 collect2: ld はステータス 1 で終了しました
 make: *** [multi-x-link] エラー 1

multi-foo-link: goo.cの中で関数 foo を二重定義

 % make multi-foo-link
 cc -o exe main.o foo.o goo-foo.o
 goo-foo.o(.text+0xa): In function `foo':
 : multiple definition of `foo'
 foo.o(.text+0x0): first defined here
 collect2: ld はステータス 1 で終了しました
 make: *** [multi-foo-link] エラー 1


最終更新日:2017/07/14 10:45:56