【问题标题】:Semaphore simulation program: Segmentation Fault error信号量模拟程序:Segmentation Fault 错误
【发布时间】:2016-08-19 00:21:14
【问题描述】:

我编写了以下程序,模拟信号量的工作。共有三个功能:lock、unlock、lockpath。

lock = 打开文件;检查文件是否已经存在,如果存在,则将当前进程置于睡眠状态。如果文件不存在,则创建它并返回 TRUE。

解锁 = 删除文件

lockpath = 返回与可能创建的文件对应的路径名。

这里是源代码:

    #include <unistd.h>

//exit();
#include <stdlib.h>

//errno
#include <errno.h>

//creat(..)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

//strcat, strcpy
#include <string.h>

//For err_sys
#include <stdio.h>

#define LOCKDIR "/tmp/"
#define MAXTRY 3
#define WAITTIME 5

enum BOOLEAN{TRUE, FALSE};

void err_sys(const char* x) {
  perror(x);
  exit(1);
}

static char* lockpath(char* name) {
  static char path[20];
  strcpy(path, LOCKDIR);
  return (strcat(path, name));
}

int lock(char* name) {
  char *path;
  int fd, incerc;
  extern int errno;
  path = lockpath(name);
  int try = 0;

  while ((fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0 
          && errno == EEXIST) {
    if (++try >= MAXTRY)
        return FALSE;
    sleep(WAITTIME);  
  }

  if (fd < 0 || close(fd) < 0)
    err_sys("lock");

  return TRUE;
}

void unlock(char* name) {
  if (unlink(lockpath(name)) < 0)
    err_sys("unlock");
}


int main(void) {

  pid_t child_process;

  child_process = fork();

  char* sem_file_name = "test_semaf";

  if (child_process != 0)
  {
    printf("\nParent process ID: %d", getpid());
  }
  else 
  { 
    printf("\nChild process ID: %d", getpid());
  }

  if (lock(sem_file_name))
  {
      printf("\nProcess with ID: %d", getpid());
      printf("\nonly, has access to %s", strcat(LOCKDIR, sem_file_name)); //****
      unlock(sem_file_name);
  } else {
    printf("\nProcess with ID: %d", getpid());
    printf("\nwas unable to get access to %s", strcat(LOCKDIR, sem_file_name));
  }

  return 0;
}

程序停止的那一行标有:****

错误是:

程序收到信号SIGSEGV,分段错误。 __strcat_ssse3 () 在 ../sysdeps/x86_64/multiarch/strcat-ssse3.S:571 571 ../sysdeps/x86_64/multiarch/strcat-ssse3.S:没有这样的文件或目录。

问题是我得到分段错误,并且找不到问题所在。对我来说,一切都很好。一个进程应该创建文件 X。然后,如果另一个进程试图创建它自己的文件 X,它是不允许的;进程进入休眠状态。允许第二个进程进行 MAXTRY 尝试。如果在 MAXTRY 尝试后未成功,则 lock() 函数返回 FALSE。最后,当一个已经成功创建了自己的 X 文件的进程现在不需要它时,文件 X 将被删除。

请您说说您认为这个程序有什么问题?提前谢谢你。


编辑: 这是解释为什么 lockpath() 函数不正确的页面的链接。

Is returning a pointer to a static local variable safe?

【问题讨论】:

  • 在调试器中运行,然后它会捕捉到正在运行的崩溃,并让您找到它发生的位置。如果它不在您的代码中,那么您将沿着调用堆栈向上走,直到您找到您的代码。在那里,您可以检查所有相关变量的值,并有望看到导致崩溃的原因。至少,请编辑您的问题以包含崩溃的位置,例如在源代码中添加评论。
  • 顺便问一下,你确定代码甚至可以编译吗?例如,在lock 函数中,您使用了变量try,但您似乎没有在任何地方定义它?此外,您可能应该在构建程序时启用更多警告,例如添加-Wall -Wextra -pedantic 编译器标志。
  • @JoachimPileborg 我已经运行了调试器,但出现了错误。似乎找不到某些文件。然而,这很奇怪。

标签: c linux semaphore


【解决方案1】:

这是导致您崩溃的原因:

strcat(LOCKDIR, sem_file_name)

在这里你尝试追加到一个文字字符串常量。

您也应该在这里使用lockpath 函数。

【讨论】:

  • 谢谢。现在我明白了问题所在。
【解决方案2】:

问题似乎在于您对strcat() 函数的误解。该函数将第二个参数中的字符串附加到第一个参数中的字符串 - 但您需要确保有足够的空间用于数据。阅读man page

也就是说

char * dest = "whatever";
strcat(dest, anything_else);

总是错的。你想要的是

char dest[SIZE] = "whatever";
strcat(dest, anything_else);

其中SIZE 足够大,缓冲区能够包含整个连接字符串。

另外,您的 lockpath() 功能已损坏。请参阅this answer 了解原因。您需要在lockpath() 函数之外创建dest 缓冲区并将其作为参数传递给它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-16
    • 2021-01-16
    • 1970-01-01
    • 2021-08-13
    • 2014-10-11
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多