1

I simply have no idea what is going wrong. I have a while loop (code block 1) that terminates immediately after one iteration of the loop. I have even commented out the entire switch statement so only the printf(...) and scanf(...) remain, and the loop seems to terminate.

The loop:

int main(int argc, char *argv[]) {
if(argc != 2) {
    printf("Usage requires hostname\n");
    return 1;
}

TCPClient client;
char str[1];
unsigned char buf[BUFLEN];
bool run = true;

printf("The commands in use are:\n"
    "h - help\n"
    "r - read ENCs (incremental)\n"
    "x - exit\n");

while(run) {
    printf("Enter a command: ");
    scanf("%s", str);

    switch(str[0]) {
      case 'h':
        printf("The commands in use are:\n"
            "h - help\n"
            "r - read ENCs (incremental)\n"
            "x - exit\n");
        break;

      case 'r':
        client.recvData(argv[1], buf, BUFLEN);

        for(int i = 0; i < BUFLEN / 4; i++) {
            if(i % 3 == 0)
                printf("\n");

            printf("Encoder %d: %d\t", i, (int)((((buf[4 * i] << 24) | (buf[4 * i + 1] << 16)) | (buf[4 * i + 2] << 8)) | (buf[4 * i + 3])));
        }
        printf("\n");
        break;

      case 'x':
        run = false;
        break;

      default:
        printf("Unrecognized command\n");
        break;
    }
}

return 0;
}

At one point, I added

if(run)
    printf("run = true");

after the while loop to see if it was breaking due to the control bool (run) being false. The result was no output, indicating that somehow, run became false. This happens no matter what the input is, or even if the switch statement is gone, in which case nothing should make run become false.

What's really strange is that in another file, I have a similar loop, except it actually works:

void *control(void *arg) {
DAC dac(5);
char str[1];
int chan = -1;
uint16_t code = -1;

while(run) {
    printf("Enter a command: ");
    scanf("%s", str);

    switch(str[0]) {
      case 'h':
        printf("The commands in use are:\n"
            "h - help\n"
            "s - set DACs\n"
            "r - read ENCs (incremental)\n"
            "t - read ENCs (cumulative)\n"
            "q - Toggle the quadrature waveform\n"
            "x - exit\n");
        break;

      case 's':
        chan = code = -1;

        printf("Enter the DAC channel: ");
        scanf("%d", &chan);

        printf("Enter the value: ");
        scanf("%hu", &code);

        pthread_mutex_lock(&lock);
        dac.setDAC(chan, code);
        pthread_mutex_unlock(&lock);
        break;

      case 'r':
        pthread_mutex_lock(&lock);
        for(int i = 0; i < BUFLEN; i++) {
            if(i % 3 == 0)
                printf("\n");
            printf("Encoder %d: %d\t", i, incBuf[i]);
            incBuf[i] = 0;
        }
        printf("\n");

        pthread_mutex_unlock(&lock);
        break;

      case 't':
        pthread_mutex_lock(&lock);
        for(int i = 0; i < BUFLEN; i++) {
            if(i % 3 == 0)
                printf("\n");
            printf("Encoder %d: %ld\t", i, cumBuf[i]);
        }
        printf("\n");

        pthread_mutex_unlock(&lock);
        break;

      case 'q':
        runSignal = !runSignal;
        if(runSignal)
            printf("Quadrature waveform enabled\n");
        else
            printf("Quadrature waveform disabled\n");

        break;

      case 'x':
        run = false;
        break;

      default:
        printf("Unrecognized command\n");
        break;
    }
}

dac.reset();
pthread_exit(NULL);
}

I'm pretty lost with what's happening...

2
  • This is a really obvious thing, but I have to ask just in case - you are actually providing an argument to the program aren't you? Commented Jul 30, 2013 at 6:43
  • Yes, I do. Either way, the program would simply quit if I didn't. The check at the top ensures that. Commented Jul 30, 2013 at 6:49

2 Answers 2

3

In while-loop scanf("%s", str); is wrong because the declaration of str[] is char str[1]; it can store only one char (as size is one). But scanf() stores at-least two char (including \0). Suppose if you inputs only c its stores as "c" that is consists of two char first c and second is \0 that causes a buffer-overflow -- Undefined behavior according to C standards.

Sign up to request clarification or add additional context in comments.

6 Comments

Interesting. Why does it work in the latter case (the working code), but not the former case? Is the buffer simply overflowing into something else in the latter case? In any case, changing the declaration to char str[2] fixed it. Thank you.
@HariGanti Is undefined behavior it doesn't guaranty that it will work always, actually in worst case it will work.
Fixing it to str[2] is not sufficient. A rogue user can simply input a string with two characters and the same error will occur.
@MartinRichtarsky yes! actually scanf() its self is not safe!
@MartinRichtarsky, while that's true, I am the only one who uses this, and it's largely a test program. Also, your argument would be true for any string length.
|
1

This is likely a stack buffer overflow of str overflowing into run during scanf. Comment out scanf to verify this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.