-1

I declared a variable as static inside a function which is called periodically. I know that declaring a variable as static makes it live during the program lifetime without redeclaring it again. Of course, as it local, it should only been modified by its function.

The strange thing is that debugging the code, The function is executed and before leaving the function, I made sure that the value of the variable is 0. In the next function call, the value of the variable is incremented by 256 before executing any line of the function. If the variable's value was 10 before leaving the function, it becomes 266 the next call. This behavior is persistent.

What can cause the local static variable's value to change between function calls?

Unfortunately I can't submit a code snippet that reproduces the problem.

Salahuddin
  • 1,617
  • 3
  • 23
  • 37
  • 4
    I guess a buffer overflow somewhere else in your code (overwriting `warningBounce`) – pmg Dec 11 '18 at 09:58
  • Ive slammed your code in a test program and it works fine here, so I back the suggestion of @pmg that something is overwriting the var. Check it with valgrind. – Nidhoegger Dec 11 '18 at 10:00
  • 3
    @Salahuddin we told you why the var might change. please check that. as you do not provide a reproducible problem we can only guess. I have extended your code to a complete program with getVoltage returning a random var and executing everything 100 times. It works for me... – Nidhoegger Dec 11 '18 at 10:03
  • OK. I'll work on it. Thanks – Salahuddin Dec 11 '18 at 10:05
  • "the value of the variable is incremented by 256 before executing any line of the function" --> This is not demonstrated in code. The way in which you have deduced a value of 256 may be in error. – chux - Reinstate Monica Dec 11 '18 at 10:05
  • Just for checking, replace `static uint16_t warningBounce = 0;` with `static char foo[200]; static uint16_t warningBounce = 0; static char bar[200];`. If the problem goes away then some other part in your program might cause the problem. Keep in mind that this does not correct the root of problem. – Jabberwocky Dec 11 '18 at 10:05
  • The increase of 256 suggests that the high-order byte of `warningBounce` is written to with a `1`. Suggest looking at global variables. – Weather Vane Dec 11 '18 at 10:08
  • Is there a reason why you can't use AddressSanitizer? – nullp0tr Dec 11 '18 at 10:09
  • 1
    The code you showed isn't doing anything useful. `warningBounce` is never read inside the function and can't be read outside the function. – Weather Vane Dec 11 '18 at 10:23
  • Thanks for your replies. I checked the value of the variable before leaving the function and when it is called again using the debugger. This is not implemented in code. Just in the debugger. I don't know AddressSanitizer. This is just a sample of the function. I know that the problem is not reproducable using it. – Salahuddin Dec 11 '18 at 10:24
  • I tried creating another variabel named `warningBounce2` without deleting the first one, and it works without problem. As you said, the variable's value is probably overwritten somewhere else in the code – Salahuddin Dec 11 '18 at 10:26
  • Sorry for posting the useless code. I deleted it as it adds no value to question – Salahuddin Dec 11 '18 at 10:28

2 Answers2

4

What can cause the local static variable's value to change between function calls?

A likely cause is that a bug in another part of your code have written to the memory location where your static variable is stored.

Take a look at this code:

void bar()
{
  static char y[2];
  y[0] = '4';
  y[1] = '2';
  printf("BAR y=%c%c  location of y is %p\n", y[0], y[1], (void*)y);

  y[2] = 0; // error! writing out of bounds
  y[3] = 1; // error! writing out of bounds
}

void foo()
{
  static uint16_t x = 0;
  printf("FOO x=%"PRIu16"  location of x is %p\n", x, (void*)&x);
  ++x;
}

int main( int argc, char **argv ){
  foo();
  foo();
  foo();
  foo();
  foo();
  bar();
  foo();
  return 0;
}

You'll notice that function bar contains a bug, i.e. it writes beyond the memory allocated for y.

On my system running this code gives:

FOO x=0  location of x is 0x100407002
FOO x=1  location of x is 0x100407002
FOO x=2  location of x is 0x100407002
FOO x=3  location of x is 0x100407002
FOO x=4  location of x is 0x100407002
BAR y=42  location of y is 0x100407000
FOO x=256  location of x is 0x100407002
    ^^^^^
    oh dear, x has changed...

So on my system the static variable x was placed just after the static variable y. So when bar is called the value of x is overwritten due to the bug in bar.

Notice: On other systems the result may be different.

So the advice is: Look for buffer overflow in the code that executes between the two calls of your function.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
3

As stated on comments and other answers it is definitely a bug, most likely a buffer overflow on another part of the code.

To find when and which part of the code modifies your static local variable you can use memory breakpoints (or data breakpoints). Start debugging and on the first function call set a memory breakpoint on the address of your variable for the size of the variable. The code will now break when the culprit code modifies this region of memory, aka your static variable.

In Visual Studio I think it is called Data Breakpoint.

gdb also has this functionality with the watch command. See how to here: Can I set a breakpoint on 'memory access' in GDB?

bolov
  • 72,283
  • 15
  • 145
  • 224