信号量模拟程序:Segmentation Fault错误
Semaphore simulation program: Segmentation Fault error
我写了下面的程序,模拟信号量的工作。一共有三个函数:lock, unlock, lockpath.
lock = 打开文件;检查文件是否已经存在,如果存在,则使当前进程进入休眠状态。如果文件不存在,则创建它并返回 TRUE。
解锁 = 删除文件
lockpath = returns可能创建的文件对应的路径名
这是源代码:
#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;
}
程序停止的行标记为:****
错误是:
Program received signal SIGSEGV, Segmentation fault.
__strcat_ssse3 () at ../sysdeps/x86_64/multiarch/strcat-ssse3.S:571
571 ../sysdeps/x86_64/multiarch/strcat-ssse3.S: No such file or directory.
问题是我遇到了 Segmentation Fault,但找不到问题出在哪里。对我来说,一切都很好。一个进程应该创建文件 X。然后,如果另一个进程试图创建它自己的文件 X,这是不允许的;该过程进入休眠状态。第二个进程被允许进行 MAXTRY 次尝试。如果在 MAXTRY 次尝试后仍未成功,则 lock() 函数 returns FALSE。最后,当一个已经成功创建了自己的 X 文件的进程现在不需要它时,文件 X 被删除。
能否请您说说您认为这个程序有什么问题?提前谢谢你。
编辑:
这是页面的 link,解释了为什么 lockpath() 函数不正确。
Is returning a pointer to a static local variable safe?
这是导致您崩溃的原因:
strcat(LOCKDIR, sem_file_name)
此处您尝试附加到文字字符串常量。
你也应该在这里使用 lockpath
函数。
问题似乎出在你对strcat()
功能的误解上。该函数将第二个参数中的字符串附加到第一个参数中的字符串 - ,但您需要确保有足够的 space 用于数据 。阅读 man page.
也就是说
char * dest = "whatever";
strcat(dest, anything_else);
总是错的。你要的是
char dest[SIZE] = "whatever";
strcat(dest, anything_else);
其中 SIZE
足以使缓冲区能够包含整个连接的字符串。
此外,您的 lockpath()
功能已损坏。请参阅 this answer 了解原因。您需要在 lockpath()
函数外部创建 dest 缓冲区并将其作为参数传递给它。
我写了下面的程序,模拟信号量的工作。一共有三个函数:lock, unlock, lockpath.
lock = 打开文件;检查文件是否已经存在,如果存在,则使当前进程进入休眠状态。如果文件不存在,则创建它并返回 TRUE。
解锁 = 删除文件
lockpath = returns可能创建的文件对应的路径名
这是源代码:
#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;
}
程序停止的行标记为:****
错误是:
Program received signal SIGSEGV, Segmentation fault. __strcat_ssse3 () at ../sysdeps/x86_64/multiarch/strcat-ssse3.S:571 571 ../sysdeps/x86_64/multiarch/strcat-ssse3.S: No such file or directory.
问题是我遇到了 Segmentation Fault,但找不到问题出在哪里。对我来说,一切都很好。一个进程应该创建文件 X。然后,如果另一个进程试图创建它自己的文件 X,这是不允许的;该过程进入休眠状态。第二个进程被允许进行 MAXTRY 次尝试。如果在 MAXTRY 次尝试后仍未成功,则 lock() 函数 returns FALSE。最后,当一个已经成功创建了自己的 X 文件的进程现在不需要它时,文件 X 被删除。
能否请您说说您认为这个程序有什么问题?提前谢谢你。
编辑: 这是页面的 link,解释了为什么 lockpath() 函数不正确。
Is returning a pointer to a static local variable safe?
这是导致您崩溃的原因:
strcat(LOCKDIR, sem_file_name)
此处您尝试附加到文字字符串常量。
你也应该在这里使用 lockpath
函数。
问题似乎出在你对strcat()
功能的误解上。该函数将第二个参数中的字符串附加到第一个参数中的字符串 - ,但您需要确保有足够的 space 用于数据 。阅读 man page.
也就是说
char * dest = "whatever";
strcat(dest, anything_else);
总是错的。你要的是
char dest[SIZE] = "whatever";
strcat(dest, anything_else);
其中 SIZE
足以使缓冲区能够包含整个连接的字符串。
此外,您的 lockpath()
功能已损坏。请参阅 this answer 了解原因。您需要在 lockpath()
函数外部创建 dest 缓冲区并将其作为参数传递给它。