Thread: Segmentation fault

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

    Segmentation fault

    I am working on a subroutine for an assembler and I am getting a segmentation fault and I'm not too sure why or what is causing it. I thought it might be my extern statements, but the issue still arises when I comment those out. Any ideas?

    Code:
    /* Pre-Processor Directives */
    #ifndef SYMBSIZE
       #define SYMBSIZE 10
    #endif
    
    typedef struct tablemem
    {
       char symbol[SYMBSIZE];
       int value;   
       int casenmbr; 
       int otherinfo;
    } tabletype;
    
    extern tabletype codetable[];
    extern int codetabsize;  
    
    int opcodeincr(int tablindx, int ni, int xbpe)
    {
       int incr = -1, eBit = xbpe;
       int caseNum = codetable[tablindx].casenmbr;
       
       /* Find what the e-bit is set to */
       if(eBit > 7) 
          eBit -= 8;
       if(eBit > 3) 
          eBit -= 4;
       if(eBit > 1)           
          eBit -= 2;
       
       /* 2-byte cases */
       if(caseNum == 2 || caseNum == 3 || caseNum == 4)
          if(eBit == 0)
             incr = 2;
       
       /* 3 or 4 byte cases */
       if(caseNum == 1)
          if(eBit == 1)
             incr = 4;
          else
             incr = 3;
       
       /* 0-byte cases */
       if(caseNum == 10 || caseNum == 11 || caseNum == 20 || caseNum == 21 ||
          caseNum == 30 || caseNum == 40 || caseNum == 41 || caseNum >= 50)
          if(eBit == 0)
             incr = 0;
       
       return incr;
    }

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Can you also include the section where you are calling opcodeincr?

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    The obvious candidate in this piece of code is the index into codetable; if it's out of range you could get a segfault. I suppose you had to comment that out, though, when you commented out the codetable declaration.

    When you get a segfault, your first step should be to use a debugger to pinpoint where the problem is, if not why it's occurring. Two good, free debuggers are Valgrind and gdb. They approach debugging in different manners, and each has its uses, but I tend to find Valgrind more useful.

    Gdb should tell you where the segfault is happening. Valgrind might be able to tell you where the actual problem is: where a segfault occurs is not necessarily where your bug is. Either way, learning how a debugger works should be one of the first things you do when leaning how to program. After all, creating bugs is also one of the first things you do!

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    I would if I could, but that's in the driver the Professor provides and we only have the object code for that. I only know that his driver works with the prototype he gave us (and that I am implementing) based on his demonstration in class, which is unfortunately also not available to us.

  5. #5
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    I will give gdb a shot and see if I can get more information, I'm not familiar with Valgrind, is that usually already installed on must UNIX systems?

  6. #6
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    Ok, so gdb is giving me this which is telling me it may be an issue with another subroutine which is possible

    Code:
    **********************
    * TESTING opcodeincr *
    **********************
    COP 3601: Spring, 2010 - 
    
    
    Enter breakup line (enter done to exit test) : CLEAR
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0000000000401535 in breakup (sourceline=0x7fbffff680 "CLEAR", components=
          {lbl = 0x7fbffff810 "", opc = 0x7fbffff7b0 "À÷ÿ¿\177", opr1 = 0x7fbffff750 "\220øÿ¿\177", opr2 = 0x7fbffff6f0 "", ni = 0x7fbffff6ec, xbpe = 0x7fbffff6e8}) at breakup.c:74
    74         while(ptr[0] == ' ' || ptr[0] == '\t')
    (gdb) quit
    The source it is refering to is:
    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], *ptr;
       char label[81], opcode[81], operand1[81], operand2[81];
       int ni = 3;
       int xbpe = *components.xbpe;
    
       /* Remove x and e bits */
       if(xbpe > 7)
          xbpe -= 8;
       if(xbpe == 7)
          xbpe -= 1;
    
       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 */
       ptr = strtok(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] == '\'')
       {
          printf("\n\nThere is a single quote!\n\n");
          ptr = strtok(workingstring, "\'");
          char temp[81];
          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;
    }
    I realize this may be a lot to digest, but any help is greatly appreciated!

  7. #7
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    Oh and incase anyone is wondering we're working on an assembler for a simple SIC / SIC/XE simulator, just so you can better understand what it's trying to accomplish

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    I seem to be able to get past the segmentation fault if I enter an entire sourceline, but then the program seems to hang. The assignment specs seem to want us to only enter a symbol though, here's the assignment specs (I'm currently working on Part A but Part B is very similar and giving the same issues) as well as the contents of the codetable

    Code:
    {"ADD"   ,{0X18, 1, 3}}, {"ADDR"  ,{0X90, 2, 2}}, {"AND"   ,{0X40, 1, 3}}, 
    {"BASE"  ,{0   ,20, 0}}, {"BYTE"  ,{0   , 5, 1}}, 
    {"CLEAR" ,{0XB4, 3, 2}}, {"COMP"  ,{0X28, 1, 3}}, {"COMPR" ,{0XA0, 2, 2}}, 
    {"CSECT" ,{0   ,50, 0}}, 
    {"DIV"   ,{0X24, 1, 3}}, {"DIVR"  ,{0X9C, 2, 2}}, 
    {"END"   ,{0   ,11, 0}},
    {"EQU"   ,{0   ,80, 0}}, {"EXTDEF",{0   ,40, 0}}, {"EXTREF",{0   ,41, 0}}, 
    {"J"     ,{0X3C, 1, 3}}, {"JEQ"   ,{0X30, 1, 3}}, {"JGT"   ,{0X34, 1, 3}},
    {"JLT"   ,{0X38, 1, 3}}, {"JSUB"  ,{0X48, 1, 3}}, {"LDA"   ,{0X00, 1, 3}},
    {"LDB"   ,{0X68, 1, 3}}, {"LDCH"  ,{0X50, 1, 3}}, {"LDL"   ,{0X08, 1, 3}},
    {"LDS"   ,{0X6C, 1, 3}}, {"LDT"   ,{0X74, 1, 3}}, {"LDX"   ,{0X04, 1, 3}}, 
    {"LTORG" ,{0   ,30, 0}}, 
    {"MUL"   ,{0X20, 1, 3}}, {"MULR"  ,{0X98, 2, 2}}, 
    {"NOBASE",{0   ,21, 0}}, {"NOP"   ,{0   ,70, 0}}, 
    {"OR"    ,{0X44, 1, 3}}, 
    {"ORG"   ,{0   ,61, 0}}, 
    {"RD"    ,{0XD8, 1, 3}}, 
    {"RESB"  ,{0   , 7, 1}}, {"RESW"  ,{0   , 8, 3}}, 
    {"RMO"   ,{0XAC, 2, 2}}, {"RSUB"  ,{0X4C, 0, 3}}, 
    {"SHIFTL",{0XA4, 4, 2}}, {"SHIFTR",{0XA8, 4, 2}}, {"STA"   ,{0X0C, 1, 3}},
    {"START" ,{0   ,10, 0}},
    {"STB"   ,{0X78, 1, 3}}, {"STCH"  ,{0X54, 1, 3}}, {"STL"   ,{0X14, 1, 3}},
    {"STS"   ,{0X7C, 1, 3}}, {"STT"   ,{0X84, 1, 3}}, {"STX"   ,{0X10, 1, 3}}, 
    {"SUB"   ,{0X1C, 1, 3}}, {"SUBR"  ,{0X94, 2, 2}}, {"TD"    ,{0XE0, 1, 3}},
    {"TIX"   ,{0X2C, 1, 3}}, {"TIXR"  ,{0XB8, 3, 2}}, 
    {"USE"   ,{0   ,60, 0}}, 
    {"WD"    ,{0XDC, 1, 3}}, 
    {"WORD"  ,{0   , 6, 3}},

  9. #9
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    My best guess is that the problem is in the line:

    Code:
    ptr = strtok(NULL, "");
    Shouldn't "" actually be " "?

  10. #10
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    No because I want to reset the pointer to the whole string and not stop at the first whitespace, at least that's what my tutor explained to me earlier today

  11. #11
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Well, here is what I think, and I may be mistaken but it's just my opinion. The line I indicated is the last line where you assign another value to ptr. Right after that, the program crashes. The problem is either in the while or in the line itself.

    Why are you always checking ptr[0] in the while loop and incrementing ptr continously? Would it be possible that ptr eventuall gets out of bounds? Just food for thought, I am not saying this is the problem since I haven't run your code.

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by williamsonj View Post
    No because I want to reset the pointer to the whole string and not stop at the first whitespace, at least that's what my tutor explained to me earlier today
    I'm worried. strtok is destructive, meaning once you call it your original string no longer exists, and is not recoverable. As far as I can tell from the standard description, this call is legal, does not change the target string, and will cause any future calls to strtok to fail. Since you never check to see whether any of your calls to strtok fail, you are therefore doomed.

  13. #13
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    I am checking ptr[0] because in the first location will be the "exceptions" to my bits that need to be set for addressing and what not so that's the only locatin that needs to be checked and if the exceptions do exist I only need to change the bits and discard the symbol (in this case @, #, *, or +) when I save the token I only need the string after that in that "location"

    It is possible for ptr to eventually go out of bounds if I am not controlling the data that is getting sent to the subroutines first, but in the cases I am doing I am in control of that and should not be running out of bounds.

    I will check if there is a difference from your suggestions though real quick

  14. #14
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by williamsonj View Post
    I am checking ptr[0] because in the first location will be the "exceptions" to my bits that need to be set for addressing and what not so that's the only locatin that needs to be checked and if the exceptions do exist I only need to change the bits and discard the symbol (in this case @, #, *, or +) when I save the token I only need the string after that in that "location"

    It is possible for ptr to eventually go out of bounds if I am not controlling the data that is getting sent to the subroutines first, but in the cases I am doing I am in control of that and should not be running out of bounds.

    I will check if there is a difference from your suggestions though real quick
    Good idea. Printf the contents of ptr in that area of your source code. See what is going on and let us know.

    Oh my I remember the days when I was taking a class similar to yours and I was up in the night just like you .

  15. #15
    Registered User
    Join Date
    Mar 2010
    Posts
    61
    Haha, thanks gotta love Systems Software 101 :-P I really appreciate the help! My professor is a smart man, but not a very good teacher, plus he's retired so he doesn't really have a vested interest in our learning, he's basically passing us for not dropping the class, but I really want to learn this stuff so I can use it later on both academically and professionally.

    P.S. this is by far the best c programming forum I have found yet! I'm going to have to take up a permanent residence here, maybe be able to help others eventually

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why am I getting segmentation fault on this?
    By arya6000 in forum C++ Programming
    Replies: 6
    Last Post: 10-12-2008, 06:32 AM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM