1
votes

I'm programming a feedback loop that takes in user commands and processes the arguments based on the command received. So far my function looks like this:

//main loop of the program that keeps repeating, which each cycle taking in one user input
 void mainLoop(){

char input[100]; // initial command
char reg[2]; // registers R1-R7 and PC
char value[20]; // register value
char breakStatus[20]; // can be either "set" or clear"
char breakAddress[80]; // address of break point in hex


//Retrieve user input
printf("Enter a command: ");
scanf("%s", &input);

//Process user input:

//set (completed)
if(strcasecmp(input, "set") == 0){
    scanf("%s", &reg);
    scanf("%s", &value);    
    set(reg, value);
    printf("register value is %s\n", value);
    printf("value[0] is %x\n", value[0]);
    //printf("Setting %s to %s!\n", reg, value);
}

//break (something's wrong here)
else if(strcasecmp(input, "break") == 0){
    scanf("%s", &breakStatus);
    scanf("%s", &breakAddress);

    printf("breakStatus is %s\n", breakStatus);
    printf("breakStatus[0] is %c\n", breakStatus[0]);
    //printf("%sing break point at address %s\n", breakStatus, breakAddress);
    executeBreak(breakStatus, breakAddress);

}


//error (completed)
else
    printf("Error: %s is not a valid command.\n", input);

 }

My problem is that whenever I try to access breakAddress[index], I get a Segmentation Fault. When I tried printf-ing breakStatus and breakAddress, they both hold the expected values (an input example would be break set x0001, where breakStatus = "set" and breakAddress = "x0001").

I know that if I use the specifier to %c, or printf("breakStatus[0] is %c\n", breakStatus[0]); , it returns a valid value. However I am passing breakStatus and breakAddress into another function, and in that function I check if breakAddress[0] == 'x', to which I promptly receive a Segmentation Fault.

I'm not sure how to handle this. I've tried casting breakAddress[0] to a char and I still get the same error.

What's really confusing me is that I pretty much coded my Set portion in the exact same way (same char[] initialization, same scanf process) and when I tried retrieving an index from one of the variables it works perfectly fine.

Below are parts of my set() and executeBreak() functions for reference:

void set(char* reg, char* val){
    if(val[0] == 'x'){ // no segmentation fault
    sscanf(val+1, "%x", &registers[r]); 
}

void executeBreak(char* stat, char* add){
    if(!(add[0] == 'x')){ // segmentation fault here (tried casting as char also)
    printf("Error: invalid break address");
    return;
    }
}

If anyone could offer some insight as to why I'm getting a Segmentation Fault in one function and none in the other it would be greatly appreciated.

EDIT: Got rid of using %s in my printf statement since that's not really where my problem is. Ideally I'd like to know why val[0] works in on function and add[0] does not, since they're given the same types of arguments.

2
You're doing no checking or enforcement of string lengths. This could very easily go all wobbly on you if the text isn't formatted exactly correctly.Jay
@DeadMG: that's not a void main().Fred Foo

2 Answers

4
votes

Heed the compiler warnings! :)

You have defined char breakStatus[20];, i.e. an array of characters. Then, in the printf statement, you've got printf("...%s...", breakStatus[0]);.

The %s formatting code expects a pointer to a string. breakStatus[0], however, is a char value. The compiler warns you about what it does to fix that: it turns the char value into a char * pointer (char value = 0 => pointer address is 0). Suppose the char value happens to be zero, then the whole thing magically turns into a NULL pointer. Trying to dereference a NULL pointer (or a 0xff pointer, perhaps... the value is essentially random, after all) almost inevitably causes a segfault.

(Update: what Vlad said... "did you mean: %c")

2
votes

Use gdb instead of debug printings:

#gdb ./myprog
(gdb) r

When the program stops with SIGSEGV take a look at the stack trace:

(gdb) bt