コードのマイグレーション

Rational Developer for AIX and Linux には、 他のプラットフォームから AIX または Linux on POWER にマイグレーションを行うときに発生する可能性のある 潜在的なエラーの原因を見つけるためにコードを分析できる静的分析ツールが備わっています。 静的分析規則の実行について詳しくは、『静的分析規則の実行』を参照してください。

以下は、他のプラットフォームからのマイグレーション時にコードに対して実行する際に特に役立つと思われる、いくつかの静的分析規則の概要です。

カテゴリー 規則 目的
ハードウェア・マイグレーションの問題      
  データ・エンディアンネスの問題 あるデータ構造から別のデータ構造へ、現行ハードウェア・アーキテクチャーのエンディアンネスには不適切な方法でデータを転送する可能性のあるコードを検出します。 char buffer[100];

// 以下のステートメントは、可能性のあるエンディアンネス問題としてフラグを立てます

int32_t myInt = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];

myInt = *((int *)buffer);
32 ビットから 64 ビットへのマイグレーションの問題      
  32 ビット・システム機能の呼び出しを回避する必要がある 32 ビット・システム機能の呼び出しを検出します。 #include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>

int main() {
   int f;
   if ( f=open("data_file",O_RDWR) < -1)
      return -1;

   off_t offset = lseek32(f,LLONG_MAX,SEEK_CUR);
   return offset;
}
  特定のシステム呼び出しを行う際に、他の整数型の代わりに size_t を使用する 関数またはメソッドの戻りの型から割り当てを行う際、またはパラメーターを渡す際に、size_t を使用する整数型の使用を検出します。 char c = strnlen(“hello”,LLONG_MAX);
  32 ビットおよび 64 ビットのアプリケーション間で動作を変更するストリング・フォーマット指定子の使用を防ぐ  

printf("Hello %l",99); // “long”

printf("Hello %z",99); // “size_t”

printf("Hello %j",99); // “intmax_t”

printf("Hello %t",99); // “ptrdiff_t”

オペレーティング・システム・マイグレーションの問題      
  OS 固有のシステム呼び出しを回避する必要がある AIX および Linux 以外のオペレーティング・システムに固有なシステム呼び出しの使用を検出します。 processorid_t i, cpuid_max;

cpuid_max = sysconf(_SC_CPUID_MAX);

for (i = 0; i <= cpuid_max; i++) {

   // p_online() は Solaris® オペレーティング・システム固有のシステム呼び出しであり、フラグが立てられます

   if (p_online(i, P_STATUS) != -1)
      printf("processor %d present\n", i);

}
  特定バージョンの AIX での POSIX セマフォーを回避する必要がある 特定バージョンの AIX で実装されていない特定の POSIX セマフォー呼び出しの使用を検出します。 sem_t sem_name;

int* ip;


sem_init(&sem_name, 0, 10);

sem_wait(&sem_name);

sem_post(&sem_name);

sem_getvalue(&sem_name, ip);

sem_destroy(&sem_name);

  非ポータブル・シンボリック・シグナル値に対する参照を回避する必要がある AIX または Linux で使用できない非ポータブル・シンボリック・シンボル値に対する参照を検出します。 switch (sig) {

   case SIGEMT:

   case SIGLWP:

   case SIGWAITING:

   case SIG_FREEZE:

   case SIGTHAW:

   case SIGCANCEL:

   case SIGLOST:

   case SIGXRES:

      printf("Signal: %d\n",sig);

}
  シグナル・ハンドラーはシグナル番号をシンボリックにのみ参照する必要がある シグナル値に、ハードコーディングされた数値定数をシンボル名の代わりに使用するシグナル・ハンドラーのケースを検出します。 実際のシグナル値は、オペレーティング・システム間で異なる場合があります。 void my_handler(int sig) {

   switch (sig) {

   case 0: // diagnostic.

       printf("0\n");
       break;

   }
}

int main() {

    struct sigaction action;

    action.sa_handler = my_handler

    return sigaction(99,&action,NULL);

}