Search code examples
csegmentation-faultmkfifo

Segmentation fault generated by mkfifo() in C


I've been trying to debug this for a few hours now and I'm still stuck...

I get a segmentation fault with a "mkfifo" call in this code (it is only a part of my entire code, since I figured the rest was not relevant here) :

#include "marketfunc.h"
#include "error.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

#define PIPE_PATH "./pipe.fifo"

struct myStruct
{
    int x;      
    int y;
    int z;  
};


struct myStruct *s;

int main(int argc, char **argv)
{

    s = malloc(sizeof(struct myStruct));

    // 'int marketfunc_init(int x)' is defined in a perfectly working extern library
    if(marketfunc_init(1) == -1) error("failed to initialize marketfunc library", 5);

    printf("test1\n");

    // Segmentation fault
    if(mkfifo(PIPE_PATH, 0666) == -1) error("failed to create pipe", 1);

    printf("test2\n");

    //...

}

Which produces this output (executableFile beeing the name of my file):

test1
bin/executableFile: Segmentation fault (core dumped)

The gdb backtrace produces this:

#0  strchrnul () at ../sysdeps/x86_64/strchr.S:32
#1  0x00007ffff7a5ed82 in __find_specmb (format=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>)
    at printf-parse.h:108
#2  _IO_vfprintf_internal (s=0x7fffffffb5a0, format=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>, 
    ap=0x7fffffffdd58) at vfprintf.c:1332
#3  0x00007ffff7a63f31 in buffered_vfprintf (s=s@entry=0x7ffff7dd41c0 <_IO_2_1_stderr_>, 
    format=format@entry=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>, args=args@entry=0x7fffffffdd58)
    at vfprintf.c:2356
#4  0x00007ffff7a5eeae in _IO_vfprintf_internal (s=0x7ffff7dd41c0 <_IO_2_1_stderr_>, 
    format=format@entry=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>, ap=ap@entry=0x7fffffffdd58)
    at vfprintf.c:1313
#5  0x00007ffff7b0c595 in error_tail (status=status@entry=4199947, errnum=errnum@entry=1, 
    message=message@entry=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>, args=args@entry=0x7fffffffdd58)
    at error.c:201
#6  0x00007ffff7b0c6ed in __error (status=4199947, errnum=1, 
    message=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>) at error.c:251
#7  0x0000000000400b78 in main (argc=1, argv=0x7fffffffdf38) at src/executableFile.c:75

Though the "pipe.fifo" file is created... Thanks in advance for your help !

EDIT:

error is simply defined as such in error.c and it's signature in error.h:

#include "error.h"
#include <stdlib.h>
#include <stdio.h>

void error(char *msg, int ret)
{
    perror(msg);
    exit(ret);
}

Solution

  • If you look at the stack trace, you will see that the call to error() shows up as:

    0x00007ffff7b0c6ed in __error (status=4199947, errnum=1, message=0xffffffffffffff60 <error: Cannot access memory at address 0xffffffffffffff60>) at error.c:251
    

    This is NOT the error() function that you defined. But rather, it is the error() function defined in error.h with the following signature:

    void error(int status, int errnum, const char *format, ...);
    

    See error.h.

    As you can see, this function expects a char* format as the last argument, which is getting some junk off the stack 0xffffffffffffff60, because you don't pass in the third argument at all. It would seem that the linker is resolving the call to error() to the wrong function.

    As a quick fix, I would rename things as follows:

    rename your file `error.h` to `error_my.h`
    
    your definition of `error()` to, say, `error_my()`
    
    replace the calls to `error()` with `error_my()`.
    

    Your code would look like:

    #include "marketfunc.h"
    #include "error_my.h" // <=======================
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #define PIPE_PATH "./pipe.fifo"
    
    struct myStruct
    {
        int x;      
        int y;
        int z;  
    };
    
    
    struct myStruct *s;
    
    int main(int argc, char **argv)
    {
    
        s = malloc(sizeof(struct myStruct));
    
        // 'int marketfunc_init(int x)' is defined in a perfectly working extern library
        if(marketfunc_init(1) == -1) error_my("failed to initialize marketfunc library", 5); // <=======================
    
        printf("test1\n");
    
        // Segmentation fault
        if(mkfifo(PIPE_PATH, 0666) == -1) error_my("failed to create pipe", 1); // <=======================
    
        printf("test2\n");
    
        //...
    
    }
    

    Print out errno when mkfifo() fails to figure out why it is failing in the first place.