2016-04-25 32 views
2

我寫了下面的程序,模擬信號量的工作。有三個功能:鎖定,解鎖,鎖定路徑。信號量模擬程序:分段故障錯誤

=打開文件;檢查文件是否已經存在,如果存在,則將當前進程置於睡眠狀態。如果文件不存在,則創建並返回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()at ../sysdeps/x86_64/multiarch/strcat-ssse3.S:571 571 ../sysdeps/x86_64/multiarch/strcat-ssse3.S:沒有這樣的文件或目錄。

問題是我得到Segmentation Fault,並且找不到問題出在哪裏。對我來說,一切都很好。一個進程應該創建文件X.然後,如果另一個進程試圖創建它自己的文件X,它是不允許的;該過程進入睡眠狀態。允許第二個進程進行MAXTRY嘗試。如果它在MAXTRY嘗試後不成功,則lock()函數返回FALSE。最後,當一個已成功創建自己的X文件的進程現在不需要它時,文件X將被刪除。

你能告訴你這個程序有什麼問題嗎?先謝謝你。


編輯: 這裏的鏈接來解釋了爲什麼lockpath()函數不正確的頁面。

Is returning a pointer to a static local variable safe?

+3

在調試器中運行,然後它會捕獲崩潰,並讓您找到它發生的位置。如果它不在你的代碼中,那麼你直接調用堆棧直到你打開代碼。在那裏你可以檢查所有涉及的變量的值,並且可以希望看到導致崩潰的原因。至少,請編輯您的問題以包含崩潰的位置,例如在源代碼中添加註釋。 –

+1

順便說一句,你確定代碼甚至*編譯*?例如,在'lock'函數中你使用了一個變量'try',但是你似乎沒有把它定義在任何地方?此外,您應該在構建程序時啓用更多警告,例如添加'-Wall -Wextra -pedantic'編譯器標誌。 –

+0

@JoachimPileborg我運行了調試器,並得到了錯誤。看來有些文件無法找到。然而,這很奇怪。 –

回答

3

這是你崩潰的原因:

strcat(LOCKDIR, sem_file_name) 

在這裏,您嘗試添加到一個字符串常量。

你也應該在這裏使用lockpath函數。

+0

謝謝。現在我明白了什麼是問題。 –

1

這個問題似乎在於你對strcat()函數的誤解。該函數將第二個參數中的字符串附加到第一個參數 - 中的字符串中,但您需要確保數據空間足夠。閱讀man page

這意味着,

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

永遠是錯的。你想要的是

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

其中SIZE足夠大的緩衝區能夠包含整個連接字符串。

另外,您的lockpath()功能已損壞。請參閱this answer瞭解原因。您需要在lockpath()函數外創建dest目標緩衝區,並將其作爲參數傳遞給它。