Search code examples
cdebugginglldb

Why does lldb debugger assign a value when i set a watchpoint?


In the following C code:

#include <stdio.h>

int main(void)
{
    unsigned i = 1;
    while (i)
    {
        i <<= 1;
    }
    return 0;
}

I first compile with debugging info as followed: gcc -g single-step.c Then I do lldb a.out. I want to see what i is doing, so i do b main and run, after which i set my watchpoint for i: watchpoint set variable i. When I do that however, lldb seems to assign a value to variable i, which it shouldn't
Watchpoint created: Watchpoint 1: addr = 0x16fdff498 size = 4 state = enabled type = w declare @ '/Users/d1ff1cult/Documents/KUL 2021-2022/IW/oefenzitting-c/les8-debugging/examples/single-step.c:5' watchpoint spec = 'i' new value: 53472
It gives i a seemingly completely random value, so what am I doing wrong?
I use CLion to write my code, but this happens in the CLion terminal as well as my macOS proper terminal. I am also using an M1 Mac.
Thanks in advance!


Solution

  • Eugene is correct.

    On my system, when I run your program, I get an initial value of 0 at the watchpoint.

    I changed the program to put your code in a function (e.g.) orig.

    I created a function fill that loops on filling in its stack frame an int array of length 100.

    From main, I call fill and then orig with b orig. Then, doing the watchpoint command, I get a value of 100.

    So, your watchpoint is displaying whatever happens to be in the stack frame for what i is assigned to. That is, the uninitialized value.

    Here is the test program I created:

    #include <stdio.h>
    #include <stdlib.h>
    
    int
    orig(void)
    {
        unsigned i = 1;
    
        while (i) {
            i <<= 1;
        }
    
        return 0;
    }
    
    void
    fill(void)
    {
        unsigned x[100];
    
        for (int i = 0;  i < 100;  ++i)
            x[i] = rand();
    }
    
    int
    main(void)
    {
    
        fill();
        orig();
    
        return 0;
    }
    

    Here is the debug output:

    > lldb ./fix1
    (lldb) target create "./fix1"
    Current executable set to './fix1' (x86_64).
    (lldb) b main
    Breakpoint 1: where = fix1`main + 4 at fix1.c:29, address = 0x000000000040117b
    (lldb) b orig
    Breakpoint 2: where = fix1`orig + 4 at fix1.c:7, address = 0x000000000040112a
    (lldb) run
    Process 193289 launched: '/tmp/watch/fix1' (x86_64)
    Process 193289 stopped
    * thread #1, name = 'fix1', stop reason = breakpoint 1.1
        frame #0: 0x000000000040117b fix1`main at fix1.c:29
       26   main(void)
       27   {
       28   
    -> 29       fill();
       30       orig();
       31   
       32       return 0;
    (lldb) c
    Process 193289 resuming
    Process 193289 stopped
    * thread #1, name = 'fix1', stop reason = breakpoint 2.1
        frame #0: 0x000000000040112a fix1`orig at fix1.c:7
       4    int
       5    orig(void)
       6    {
    -> 7        unsigned i = 1;
       8    
       9        while (i) {
       10           i <<= 1;
    (lldb) watchpoint set variable i
    Watchpoint created: Watchpoint 1: addr = 0x7fffffffdd6c size = 4 state = enabled type = w
        declare @ '/tmp/watch/fix1.c:7'
        watchpoint spec = 'i'
        new value: 100