Migrating Your Code

Rational Developer for AIX and Linux provides static analysis tooling that can analyze your code to find potential sources of error that you may encounter when migrating to AIX or Linux on POWER from another platform. For more information on running static analysis rules, see Running Static Analysis Rules.

The following is a brief overview of some static analysis rules that may be particularly helpful to run on your code when migrating from another platform

Category Rule Purpose Examples
Hardware Migration Issues      
  Data Endianness Issues Detects code that may be transferring data from one data structure to another in a manner that is improper for the current hardware architecture’s endianness. char buffer[100];

// these statements should flag as possible endianness problems

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

myInt = *((int *)buffer);
32-bit To 64-bit Migration Issues      
  Calls to 32-bit system functions should be avoided Detects calls to 32-bit system functions #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 should be used instead of other integral types when making certain system calls Detects usage of integral types where size_t should be used to assign from a function/method’s return type or when passing parameters. char c = strnlen(“hello”,LLONG_MAX);
  Use of string format specifiers that change behavior between 32-bit and 64-bit applications is discouraged  

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

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

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

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

Operating System Migration Issues      
  OS specific system calls should be avoided Detects usage of system calls that are specific to operating systems other than AIX and Linux. processorid_t i, cpuid_max;

cpuid_max = sysconf(_SC_CPUID_MAX);

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

   // p_online() is a Solaris® operating system specific system call and will be flagged

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

}
  POSIX semaphores should be avoided on certain versions of AIX Detects usage of certain POSIX semaphore calls that are not implemented on certain versions of AIX. 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);

  References to non-portable symbolic signal values should be avoided Detects references to non-portable symbolic symbol values that are not available on AIX or 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);

}
  Signal handlers should only refer to signal numbers symbolically Detects cases in signal handlers that use hardcoded numeric constants for signal values instead of symbolic names. Actual signal values vary between some operating systems. 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);

}