Задать вопрос
@vladislav9619996

Почему появляется ошибка segmentation fault но при повторном запуске программы её нет?

Мне нужно включать и выключать gpio38 для этого использую код на с++ но раз через раз выскакивает ошибка segmentation fault (то есть первый раз запустил все нормально второй раз запустил ошибка третий все нормально четвёртый ошибка и так далее причем в коде ничего не меняя)
/* gpio38.c */
#include <stdio.h>
#include <stdlib.h>
#define GPIO_PATH   "/sys/class/gpio"
#define GPIO38_PATH “/sys/class/gpio/gpio38”
 
int main( int argc, char * argv[] )
{
   FILE * fp;
 
  int a=0;
 
  fp = fopen( GPIO_PATH"/export","w");
  
  if ( fp == NULL ) {
      printf(“can not open file\n”);
      return EXIT_FAILURE;
  }
  fprintf( fp, "38");
  fclose( fp );
 
  fp = fopen( GPIO38_PATH”/direction”, “w”);
 
  if ( fp == NULL ) {
      printf(“can not open file\n”);
      return EXIT_FAILURE;
  }
 if(a==1)
  fprintf( fp, “high”);
else fprintf( fp, “low”);
  fclose(fp);
 
  fp = fopen( GPIO38_PATH”/value”, “w”);
  
  if ( fp == NULL ) {
      printf(“can not open file\n”);
      return EXIT_FAILURE;
  }
 
  fclose(fp);
}

Подскажите в чем ошибка не могу понять почему такое странное поведение
  • Вопрос задан
  • 614 просмотров
Подписаться 3 Средний 1 комментарий
Пригласить эксперта
Ответы на вопрос 4
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Я не вижу криминала который мог бы привести к segfault в приведённой программе.
Почему поведение может отличаться между запусками -- например потому что запись в файл /sys/class/gpio/export меняет состояние системы и запоминается между запусками.
Кроме того, согласно https://www.kernel.org/doc/Documentation/gpio/sysfs.txt в direction надо писать in или out, а high или low нужно писать в value. Сегфолта от этого быть не должно, тем не менее.

Что происходит, если собрать программу с отладочной информацией и запустить так, чтобы она упала под отладчиком?

UPD: посмотрел ещё немного... В приведённом исходном тексте кривые юникодные кавычки. Рекомендую исправить на ASCII, либо вставить исходный текст как есть, без фокусов.
Ответ написан
@nApoBo3
Попробуйте использовать другой указатель для второго файла или добавить sleep между закрытием и открытием.
Ответ написан
@andiges
Почему программа падает с SIGSEGV мне тоже не совсем понятно.

В отладчике вовремя вознкновения ошибки в строке fp = fopen( GPIO38_PATH”/direction”, “w”);
fp равен 0 из за этого все валится на другой раз результат нормальный


Между экспортом и использованием (fopen(...direction)) стоит использовать небольшую паузу, ядру нужно немного время, что-бы экспортировать gpio.

Ну и странные кавычки конечно как сказал jcmvbkbc. может стоит компилировать так:
gcc main.c -Wall -Wpedantic

Так же можно проверить закрываются ли файлы, но это всё-равно не даёт SIGSEGV.
Ответ написан
Комментировать
@shmelevka
Эм могу ошибаться, но разве не надо почистить ь fp до того как заново использовать. Таким образом вы назначаете fp указателем на новый файл, а в области памяти остались остатки от прошлого. delete в помощь.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы