ccross-compilingraspberry-pi3archlinuxarchlinux-arm

Cross Compiling For Arch Arm Does Not Produce A Functional Executable


I installed Arch Arm onto an Rpi3, then rsync'd sysroot to an x86_64 Arch Linux installed on a Lenovo thinkpad.

I then installed the arm-linux-gnueabihf Linaro cross compiler

To avoid any problems I used absolute paths in compilation:

/home/sameh/Rpi/Compiler/gcc-linaro-7.2.1-2017.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc\
 --sysroot=/home/sameh/Rpi/Arch/ArmV7/root\
 -o stress stress.c -lm

The code compiles fine, however when I execute it on the Rpi3 it has no output.

It doesn't freez the Pi, I can ps aux and see the child processes created by fork().

But none of the debug statements are printed and none of the processes exit.

Edit

This code is based on the stress library. For an MCVE I minimized it to only the hogcpu function

#include <ctype.h>
#include <errno.h>
#include <libgen.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>

int hogcpu (void);

int
hogcpu (void)
{
  for(int i=0; i < 1000000; i++)
    sqrt (rand ());
  return 0;
}

int main()
{

  struct timespec start, end;
  double cpu_time_used;
  int pid, children = 0, retval = 0;
  long forks;
  int do_dryrun = 0;
  long long do_backoff = 3000;

  long long do_cpu = 1;
  long long backoff, timeout = 0;

  /* Calculate the backoff value so we get good fork throughput.  */
  backoff = do_backoff * forks;

  clock_gettime(CLOCK_REALTIME, &start); 

  while ((forks = (do_cpu + do_io + do_vm + do_hdd)))
  {
    if (do_cpu)
    {
      switch (pid = fork ())
        {
        case 0:            /* child */
          alarm (timeout);
          usleep (backoff);
          exit (hogcpu ());
        case -1:           /* error */
          break;
        default:
          ++children;
        }
      --do_cpu;
    }

  }
  /* Wait for our children to exit.  */
  while (children)
  {
    int status, ret;

    if ((pid = wait (&status)) > 0)
    {
      --children;
      if (WIFEXITED (status))
      {
        if ((ret = WEXITSTATUS (status)) == 0)
        {
          printf( "<-- worker %i returned normally\n", pid);
        }
        else
        {
          printf( "<-- worker %i returned error %i\n", pid, ret);
          ++retval;
          printf( "now reaping child worker processes\n");
          if (signal (SIGUSR1, SIG_IGN) == SIG_ERR)
            printf( "handler error: %s\n", strerror (errno));
          if (kill (-1 * getpid (), SIGUSR1) == -1)
            printf( "kill error: %s\n", strerror (errno));
        }
      }
    }
  }

  clock_gettime(CLOCK_REALTIME, &end); 
  cpu_time_used = (end.tv_nsec = start.tv_nsec) / 1000000000.0;
  /* Print final status message.  */
  if (retval)
  {
    printf( "failed run completed in %.2f s\n", cpu_time_used);
  }
  else
  {
    printf( "successful run completed in -- %.2f s\n", cpu_time_used);
  }

  exit (retval);
}

I can successfully compile and execute it on the the Pi with:

[alarm@control ~]$ gcc stress.c -o stress -lm
[alarm@control ~]$ ./stress 
<-- worker 16834 returned normally
<-- worker 16835 returned normally
<-- worker 16836 returned normally
successful run completed in -- 0.90 s

However, when cross compiled and transferred to the Pi, the behavior described above is what I am seeing.

Note

This may well have to do with the clock_gettime call. When I replace this with a clock() function call, I can compile and run it on the laptop, but compiling on the Pi with gcc has the same behavior above.

When using clock_gettime and compiling on the Pi, it works fine.


Solution

  • The issue here was how the long forks; variable was initialized. I am not well versed in compilers, but because forks was not initialized, the calculation backoff = do_backoff * forks; resulted in a random negative number.

    This blocked the call usleep (backoff); from finishing. So initializing forks to 1 fixed the problem.

    I would have thought that forks should have been initialized to 0 by the compiler as past of the bss_data so I am not sure why it didn't. Probably need more research into that part, but the code executes fine now with cross compiling.