iovisor / iovisor/bcc

multiple variables declared in one line have their values wrongly overwritten

Open
#5,116 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
22.7k
Forks
4.1k
Avg merge
10d 4h
Merged PRs (30d)
3

Description

I've come across a behavior that looks very suspicious while when declaring multiple variables in one line and then updating one of the values. I'm using CLang 14, couldn't get 15+ to work, even in Godbolt, which is also failing: https://godbolt.org/z/vh1rWT79a, so I'm not sure if this is a CLang bug (or was, couldn't test newer versions).

Here's a reproduction:
```c
int hello(void *ctx) {
u64 last_key, total_key = 0;
total_key = 1;

bpf_trace_printk("%d, %d", total_key, last_key);
bpf_trace_printk("%d, %d", total_key, last_key);

return 0;
}
```
> If I swap the variables position in declaration (`total_key, last_key`), or if I declare them in different lines, it stops happening.

When attached to a kprobe (say `sys_sync`), the output looks like:
```
b'1, -1881840923'
b'1, 0'
```
The first print contains the wrong value for `last_key`, should be `0` as well.

Disassembled with `BPF.disassemble_func` gives the following:
```asm
0: (b7) r6 = 0
1: (73) *(u8*)(r10 -2) = r6
2: (b7) r7 = 25637
3: (6b) *(u16*)(r10 -4) = r7
4: (b7) r8 = 539780133
5: (63) *(u32*)(r10 -8) = r8
6: (bf) r1 = r10
7: (07) r1 += -8
8: (b7) r2 = 7
9: (b7) r3 = 1
10: (85) call bpf_trace_printk#6
11: (6b) *(u16*)(r10 -12) = r7
12: (63) *(u32*)(r10 -16) = r8
13: (73) *(u8*)(r10 -10) = r6
14: (bf) r1 = r10
15: (07) r1 += -16
16: (b7) r2 = 7
17: (b7) r3 = 1
18: (85) call bpf_trace_printk#6
19: (b7) r0 = 0
20: (95) exit
```

Disassembled ASM with variables swapped
Notice the `r4 = 0` at position 10.

```asm
0: (b7) r6 = 0
1: (73) *(u8*)(r10 -2) = r6
2: (b7) r7 = 25637
3: (6b) *(u16*)(r10 -4) = r7
4: (b7) r8 = 539780133
5: (63) *(u32*)(r10 -8) = r8
6: (bf) r1 = r10
7: (07) r1 += -8
8: (b7) r2 = 7
9: (b7) r3 = 1
10: (b7) r4 = 0
11: (85) call bpf_trace_printk#6
12: (6b) *(u16*)(r10 -12) = r7
13: (63) *(u32*)(r10 -16) = r8
14: (73) *(u8*)(r10 -10) = r6
15: (bf) r1 = r10
16: (07) r1 += -16
17: (b7) r2 = 7
18: (b7) r3 = 1
19: (b7) r4 = 0
20: (85) call bpf_trace_printk#6
21: (b7) r0 = 0
22: (95) exit
```

What's the catch here? Am I missing something? Was this known and fixed after CLang 14? Is this even a bug? I'm a bit lost and some help would be appreciated 😅 .

I've built BCC from source from the master branch, at rev `cb1ba20f4800f556dc940682ba7016c50bd0a3ac`. Kernel is `6.11.0-061100-generic`.
```
root@ubuntu-64gb-hil-3:~/bepeefe/bcc# clang-14 -v
Ubuntu clang version 14.0.0-1ubuntu1.1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/11
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/11
Candidate multilib: .;@m64
Selected multilib: .;@m64
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.