Thread: Segmentation Fault of death

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    61

    Segmentation Fault of death

    I am getting a segmentation fault in a function and am not sure if I have correctly pinpointed the location. And if I have I don't have a clue of how to resolve the issue.

    Here is the gdb report I get:
    Code:
    Program received signal SIGSEGV, Segmentation fault.
    0x00000000004023c7 in breakup (
        sourceline=0x504c60 ".CHECK   getsource removal of initial blank lines", 
        components=
          {lbl = 0x7fbffff9d0 "\001", opc = 0x402399 "\213EôÉÃ\220\220UH\211åH\201ìp\002", opr1 = 0x5a <Address 0x5a out of bounds>, opr2 = 0x509b10 "", ni = 0xa0d0c0b0920, xbpe = 0x1a00000000}) at breakup.c:19
    19         int xbpe = *components.xbpe;
    (gdb) backtrace
    #0  0x00000000004023c7 in breakup (
        sourceline=0x504c60 ".CHECK   getsource removal of initial blank lines", 
        components=
          {lbl = 0x7fbffff9d0 "\001", opc = 0x402399 "\213EôÉÃ\220\220UH\211åH\201ìp\002", opr1 = 0x5a <Address 0x5a out of bounds>, opr2 = 0x509b10 "", ni = 0xa0d0c0b0920, xbpe = 0x1a00000000}) at breakup.c:19
    #1  0x0000000000401e05 in pass1 () at pass1.c:47
    #2  0x0000000000400e81 in main ()
    From what I can tell the problem seems to exist in the following code:
    Code:
    int xbpe = *components.xbpe;
    Which is part of the following function:
    Code:
    /* Pre-Processor Directives */
    #include <string.h>
    
    struct toklist
    {
       char *lbl;
       char *opc;
       char *opr1;
       char *opr2;
       int *ni;
       int *xbpe;
    } ;
    
    void breakup(char sourceline[], struct toklist components)
    {
       char workingstring[81], temp[81], *ptr;
       char label[81], opcode[81], operand1[81], operand2[81];
       int ni = 3, bp = 0;
       int xbpe = *components.xbpe;
    
       /* Remove x and e bits */
       if(xbpe > 7)
          xbpe -= 8;
       if(xbpe > 3)
       {
          bp += 4;
          xbpe -= 4;
       }
       if(xbpe > 1)
       {
          bp += 2;
          xbpe -= 2;
       }
       xbpe = 0;
    
       strcpy(workingstring, sourceline);
       strtok(workingstring, "\n");
       label[0] = '\0';
       opcode[0] = '\0';
       operand1[0] = '\0';
       operand2[0] = '\0';
    
       /* Check for a label */
       if(workingstring[0] == ' ' || workingstring[0] == '\t')
       {/* No label, tokenize opcode */
          if((ptr = strtok(workingstring, " \t")) != NULL)
          {
             if(ptr[0] == '*')
             {
                ptr = ptr + 1;
                ni = 0;
             }
             if(ptr[0] == '+')
             {
                ptr = ptr + 1;
                xbpe += 1;
             }
             strcpy(opcode, ptr);
          }
       }
       else
       {/* Tokenize label and opcode */
          if((ptr = strtok(workingstring, " \t")) != NULL)
             strcpy(label, ptr);
          if((ptr = strtok(NULL, " \t")) != NULL)
          {
             if(ptr[0] == '*')
             {
                ptr = ptr + 1;
                ni = 0;
             }
             if(ptr[0] == '+')
             {
                ptr = ptr + 1;
                xbpe += 1;
             }
             strcpy(opcode, ptr);
          }
       }
    
       /* Remove White Space */
       if((ptr = strtok(NULL, "")) != NULL)
       {
          while(ptr[0] == ' ' || ptr[0] == '\t')
             ptr = ptr + 1;
          strcpy(workingstring, ptr);
       }
    
       /* Set n bit for indirect addressing */
       if(workingstring[0] == '@')
       {
          strcpy(workingstring, workingstring + 1);
          ni = 2;
       }
       /* Set i bit for immediate addressing */
       if(workingstring[0] == '#')
       {
          strcpy(workingstring, workingstring + 1);
          ni = 1;
       }
    
       /* Check for single quote */
       if(workingstring[1] == '\'' || workingstring[2] == '\'')
       {
          ptr = strtok(workingstring, "\'");
          strcpy(temp, ptr);
          strcat(temp, "\'");
          ptr = strtok(NULL, "\'");
          strcat(temp, ptr);
          strcat(temp, "\'");
          strcpy(operand1, temp);
       }
       else
          /* Tokenize operand1 */   
          if((ptr = strtok(workingstring, ", \t")) != NULL)
             strcpy(operand1, ptr);
    
       /* Tokenize operand2 */
       if((ptr = strtok(NULL, ", \t")) != NULL)
          strcpy(operand2, ptr);
       /* If there is an operand2 set x bit */
       if(strncmp(operand2, "\0", 1) != 0)
          xbpe += 8;
    
       /* Set values in the components */
       strcpy(components.lbl, label);
       strcpy(components.opc, opcode);
       strcpy(components.opr1, operand1);
       strcpy(components.opr2, operand2);
       *components.ni = ni;
       *components.xbpe = xbpe + bp;
    }

  2. #2
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    Have you checked if components.xbpe is NULL?

  3. #3
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Components IS NOT A POINTER, so DON'T dereference it.

    EDIT: Nevermind, I see what you are doing now.

    Is components.xbpe pointing to anything?
    Last edited by claudiu; 04-08-2010 at 07:20 PM.

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    The member select operator has a higher precedence than the dereference operator.

    C Operator Precedence Table

  5. #5
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by Memloop View Post
    The member select operator has a higher precedence than the dereference operator.

    C Operator Precedence Table
    Yeah I just read that online as well. I prefer not remembering the entire precedence table so I just use parants when needed.

  6. #6
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    components.xbpe should be pointing to an integer value from 0 to 15

    EDIT: actually, now that I look at it, I don't think it gets set in the calling function. In the previous assignments my professor supplied random ints that we basically stripped and built back up. But now that I'm calling it from a function of my own, perhaps I should set everything to zero?

  7. #7
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    Doing that I can see that xbpe is being pulled in as 0 but I still get a segmentation fault and it appears to be coming from the same line

    Code:
    Program received signal SIGSEGV, Segmentation fault.
    0x000000000040251b in breakup (
        sourceline=0x504dc0 ".CHECK   getsource removal of initial blank lines", 
        components=
          {lbl = 0x7fbffff850 "", opc = 0x402fe0 "H\211\\$èL\211d$øL\215%Ç\b\020", opr1 = 0x7fbffff9d0 "\001", opr2 = 0x4024ed "\213EôÉÃ\220\220UH\211åH\201ìp\002", ni = 0x5a, xbpe = 0x0}) at breakup.c:19
    19         int xbpe = *components.xbpe;

  8. #8
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Initialize what to 0? A pointer is AN ADDRESS. If the pointer doesn't point to a specific integer in your program, you can't initialize the value it's pointing at because you don't know what part of memory it's pointing at. You can't do:

    Code:
    int *x;
    
    *x = 3;
    This is basically what you are doing. The correct way to use a pointer is like this:

    Code:
    int *d;
    int x = 10;
    d = &x;
    *d = 3;

  9. #9
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    So does this not work?

    Code:
    struct toklist
    {
       char *lbl;
       char *opc;
       char *opr1;
       char *opr2;
       int *ni;
       int *xbpe;
    } ;
    
    struct toklist components;
    
    components.xbpe = 0;

  10. #10
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Nope, because xbpe is pointing somewhere in pointer-heaven (or worse in some memory location used by another program).

  11. #11
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    So perhaps something like this?

    Code:
    struct toklist
    {
       char *lbl;
       char *opc;
       char *opr1;
       char *opr2;
       int *ni;
       int *xbpe;
    } ;
    
    struct toklist components;
    
    int zero = 0;
    
    components.xbpe = &zero;
    components.ni = &zero;

  12. #12
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    Nope, that doesn't work either lol

  13. #13
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    No, now they are both pointing to zero. Zero is on the stack so when you exit that function they will be pointing to pointer heaven again.

    If you just want it to be zero, just don't declare it as a pointer but rather as a normal int.

    The question is: what exactly do you use xbpe for when you INITIALIZE a toklist object?

  14. #14
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    I guess I need to figure out how to set the value of xbpe in components so that I can make sure I'm not getting NULL when trying to get the value out of xbpe else where. Correct? Am I correct in assuming that the segmentation fault is being caused because I am trying to dereference components.xbpe and getting NULL? Or am I still completely lost?

    The struct toklist was provided by the professor and so cannot be changed.

  15. #15
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    What is happening to xbpe is the same thing that happens in this example:

    Code:
    int d;
    
    printf("%d", d);
    You will probably get a garbage value for d. Because d is NOT INITIALIZED. Variables both pointer or not are not automatically initialized in C unless they are global variables.

    So when you say:

    Code:
    int *int_ptr;
    int_ptr points somewhere in memory but you have no idea where (IT IS NOT NULL). Try to visualize a pointer as a mailbox. The pointer is the mailbox, and what is inside the mailbox is its dereferenced value. So when you declare a pointer, it can be <any> mailbox, just like when you declare an int it can have any value. Unless you need a variable to hold the address of another variable (i.e. which is what a pointer is), just use a value.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  2. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  3. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  4. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM