Перекрестная компиляция для арочного плеча не дает функционального исполняемого файла - PullRequest
0 голосов
/ 25 апреля 2018

Я установил Arch Arm на Rpi3, затем rsync'd sysroot для x86_64 Arch Linux, установленного на ThinkPad Lenovo.

Затем я установил arm-linux-gnueabihf Кросс-компилятор Linaro

Чтобы избежать каких-либо проблем, я использовал абсолютные пути при компиляции:

/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

Код компилируется нормально, однако, когда я выполняю его на Rpi3, он не выводится.

Он не замораживает Pi, я могу ps aux и увидеть дочерние процессы, созданные fork().

Но ни один из операторов отладки не печатается, и ни один из процессов не завершается.

Редактировать

Этот код основан на библиотеке стресс . Для MCVE я свернул его только до функции hogcpu

#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);
}

Я могу успешно скомпилировать и выполнить его на Пи с помощью:

[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

Однако при кросс-компиляции и передаче в Pi описанное выше поведение - вот что я вижу.

Примечание

Это вполне может быть связано с вызовом clock_gettime. Когда я заменяю это вызовом функции clock(), я могу скомпилировать и запустить его на ноутбуке, но компиляция на Pi с gcc ведет себя так же, как описано выше.

При использовании clock_gettime и компиляции на Pi он работает нормально.

1 Ответ

0 голосов
/ 05 мая 2018

Проблема заключалась в том, как была инициализирована переменная long forks;.Я не очень разбираюсь в компиляторах, но из-за того, что forks не был инициализирован, вычисление backoff = do_backoff * forks; привело к случайному отрицательному числу.

Это заблокировало вызов usleep (backoff); от завершения.Таким образом, инициализация forks к 1 устранила проблему.

Я бы подумал, что forks должен был быть инициализирован компилятором 0 как прошлое bss_data, поэтому я не уверен, почему этоне сделал.Вероятно, потребуется больше исследований в этой части, но код теперь прекрасно работает с кросс-компиляцией.

...