Skip to content

Commit ba64f03

Browse files
pjsgyonghong-song
authored andcommitted
Fixes #2518 -- weird behaviour of lookup_or_init (#2520)
* Allow lookup_or_init to return NULL (rather than just returning from the current function) * Fixed a couple of bad edits found when running tests. Also fixed a bug in the test runner. Also fixed a bug in libbcc where the python signature did not match the actual implementation.
1 parent c99c7c4 commit ba64f03

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+198
-84
lines changed

docs/reference_guide.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ Examples in situ:
767767

768768
Syntax: ```*val map.lookup_or_init(&key, &zero)```
769769

770-
Lookup the key in the map, and return a pointer to its value if it exists, else initialize the key's value to the second argument. This is often used to initialize values to zero.
770+
Lookup the key in the map, and return a pointer to its value if it exists, else initialize the key's value to the second argument. This is often used to initialize values to zero. If the key cannot be inserted (e.g. the map is full) then NULL is returned.
771771

772772
Examples in situ:
773773
[search /examples](https://github.com/iovisor/bcc/search?q=lookup_or_init+path%3Aexamples&type=Code),

docs/tutorial_bcc_python_developer.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,9 @@ int count(struct pt_regs *ctx) {
559559
bpf_probe_read(&key.c, sizeof(key.c), (void *)PT_REGS_PARM1(ctx));
560560
// could also use `counts.increment(key)`
561561
val = counts.lookup_or_init(&key, &zero);
562-
(*val)++;
562+
if (val) {
563+
(*val)++;
564+
}
563565
return 0;
564566
};
565567
""")
@@ -678,7 +680,9 @@ int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
678680

679681
// could also use `stats.increment(key);`
680682
val = stats.lookup_or_init(&key, &zero);
681-
(*val)++;
683+
if (val) {
684+
(*val)++;
685+
}
682686
return 0;
683687
}
684688
```

examples/cpp/LLCStat.cc

+6-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ int on_cache_miss(struct bpf_perf_event_data *ctx) {
4343
4444
u64 zero = 0, *val;
4545
val = miss_count.lookup_or_init(&key, &zero);
46-
(*val) += ctx->sample_period;
46+
if (val) {
47+
(*val) += ctx->sample_period;
48+
}
4749
4850
return 0;
4951
}
@@ -54,7 +56,9 @@ int on_cache_ref(struct bpf_perf_event_data *ctx) {
5456
5557
u64 zero = 0, *val;
5658
val = ref_count.lookup_or_init(&key, &zero);
57-
(*val) += ctx->sample_period;
59+
if (val) {
60+
(*val) += ctx->sample_period;
61+
}
5862
5963
return 0;
6064
}

examples/cpp/TCPSendStack.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ int on_tcp_send(struct pt_regs *ctx) {
3939
4040
u64 zero = 0, *val;
4141
val = counts.lookup_or_init(&key, &zero);
42-
(*val)++;
42+
if (val) {
43+
(*val)++;
44+
}
4345
4446
return 0;
4547
}

examples/cpp/UseExternalMap.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ int on_sched_switch(struct tracepoint__sched__sched_switch *args) {
5656
__builtin_memcpy(&key.prev_comm, args->prev_comm, 16);
5757
__builtin_memcpy(&key.next_comm, args->next_comm, 16);
5858
val = counts.lookup_or_init(&key, &zero);
59-
(*val)++;
59+
if (val) {
60+
(*val)++;
61+
}
6062
6163
return 0;
6264
}

examples/lua/offcputime.lua

+3-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ int oncpu(struct pt_regs *ctx, struct task_struct *prev) {
6565
key.stack_id = stack_traces.get_stackid(ctx, stack_flags);
6666
6767
val = counts.lookup_or_init(&key, &zero);
68-
(*val) += delta;
68+
if (val) {
69+
(*val) += delta;
70+
}
6971
return 0;
7072
}
7173
]]

examples/lua/task_switch.lua

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
3333
key.prev_pid = prev->pid;
3434
3535
val = stats.lookup_or_init(&key, &zero);
36-
(*val)++;
36+
if (val) {
37+
(*val)++;
38+
}
3739
return 0;
3840
}
3941
]]

examples/networking/distributed_bridge/tunnel.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ int handle_ingress(struct __sk_buff *skb) {
3838
struct vni_key vk = {ethernet->src, *ifindex, 0};
3939
struct host *src_host = mac2host.lookup_or_init(&vk,
4040
&(struct host){tkey.tunnel_id, tkey.remote_ipv4, 0, 0});
41-
lock_xadd(&src_host->rx_pkts, 1);
41+
if (src_host) {
42+
lock_xadd(&src_host->rx_pkts, 1);
43+
}
4244
bpf_clone_redirect(skb, *ifindex, 1/*ingress*/);
4345
} else {
4446
bpf_trace_printk("ingress invalid tunnel_id=%d\n", tkey.tunnel_id);

examples/networking/tunnel_monitor/monitor.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,14 @@ ip: ;
126126
swap_ipkey(&key);
127127
struct counters zleaf = {0};
128128
struct counters *leaf = stats.lookup_or_init(&key, &zleaf);
129-
if (is_ingress) {
130-
lock_xadd(&leaf->rx_pkts, 1);
131-
lock_xadd(&leaf->rx_bytes, skb->len);
132-
} else {
133-
lock_xadd(&leaf->tx_pkts, 1);
134-
lock_xadd(&leaf->tx_bytes, skb->len);
129+
if (leaf) {
130+
if (is_ingress) {
131+
lock_xadd(&leaf->rx_pkts, 1);
132+
lock_xadd(&leaf->rx_bytes, skb->len);
133+
} else {
134+
lock_xadd(&leaf->tx_pkts, 1);
135+
lock_xadd(&leaf->tx_bytes, skb->len);
136+
}
135137
}
136138
return 1;
137139
}

examples/networking/vlan_learning/vlan_learning.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ int handle_phys2virt(struct __sk_buff *skb) {
3333
int out_ifindex = leaf->out_ifindex;
3434
struct ifindex_leaf_t zleaf = {0};
3535
struct ifindex_leaf_t *out_leaf = egress.lookup_or_init(&out_ifindex, &zleaf);
36-
// to capture potential configuration changes
37-
out_leaf->out_ifindex = skb->ifindex;
38-
out_leaf->vlan_tci = skb->vlan_tci;
39-
out_leaf->vlan_proto = skb->vlan_proto;
36+
if (out_leaf) {
37+
// to capture potential configuration changes
38+
out_leaf->out_ifindex = skb->ifindex;
39+
out_leaf->vlan_tci = skb->vlan_tci;
40+
out_leaf->vlan_proto = skb->vlan_proto;
41+
}
4042
// pop the vlan header and send to the destination
4143
bpf_skb_vlan_pop(skb);
4244
bpf_clone_redirect(skb, leaf->out_ifindex, 0);

examples/tracing/mallocstacks.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@
4747
// could also use `calls.increment(key, size);`
4848
u64 zero = 0, *val;
4949
val = calls.lookup_or_init(&key, &zero);
50-
(*val) += size;
50+
if (val) {
51+
(*val) += size;
52+
}
5153
return 0;
5254
};
5355
""")

examples/tracing/strlen_count.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
bpf_probe_read(&key.c, sizeof(key.c), (void *)PT_REGS_PARM1(ctx));
3535
// could also use `counts.increment(key)`
3636
val = counts.lookup_or_init(&key, &zero);
37-
(*val)++;
37+
if (val) {
38+
(*val)++;
39+
}
3840
return 0;
3941
};
4042
""")

examples/tracing/task_switch.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
1616

1717
// could also use `stats.increment(key);`
1818
val = stats.lookup_or_init(&key, &zero);
19-
(*val)++;
19+
if (val) {
20+
(*val)++;
21+
}
2022
return 0;
2123
}

src/cc/frontends/clang/b_frontend_action.cc

-1
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,6 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
782782
txt += "if (!leaf) {";
783783
txt += " " + update + ", " + arg0 + ", " + arg1 + ", BPF_NOEXIST);";
784784
txt += " leaf = " + lookup + ", " + arg0 + ");";
785-
txt += " if (!leaf) return 0;";
786785
txt += "}";
787786
txt += "leaf;})";
788787
} else if (memb_name == "increment") {

src/python/bcc/libbcc.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
lib.bpf_attach_socket.argtypes = [ct.c_int, ct.c_int]
9090
lib.bcc_func_load.restype = ct.c_int
9191
lib.bcc_func_load.argtypes = [ct.c_void_p, ct.c_int, ct.c_char_p, ct.c_void_p,
92-
ct.c_size_t, ct.c_char_p, ct.c_uint, ct.c_int, ct.c_char_p, ct.c_uint]
92+
ct.c_size_t, ct.c_char_p, ct.c_uint, ct.c_int, ct.c_char_p, ct.c_uint, ct.c_char_p]
9393
_RAW_CB_TYPE = ct.CFUNCTYPE(None, ct.py_object, ct.c_void_p, ct.c_int)
9494
_LOST_CB_TYPE = ct.CFUNCTYPE(None, ct.py_object, ct.c_ulonglong)
9595
lib.bpf_attach_kprobe.restype = ct.c_int

tests/cc/test_bpf_table.cc

+6-2
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,9 @@ TEST_CASE("test bpf stack table", "[bpf_stack_table]") {
182182
int stack_id = stack_traces.get_stackid(ctx, BPF_F_REUSE_STACKID);
183183
int zero = 0, *val;
184184
val = id.lookup_or_init(&zero, &stack_id);
185-
(*val) = stack_id;
185+
if (val) {
186+
(*val) = stack_id;
187+
}
186188
187189
return 0;
188190
}
@@ -233,7 +235,9 @@ TEST_CASE("test bpf stack_id table", "[bpf_stack_table]") {
233235
int stack_id = stack_traces.get_stackid(ctx, BPF_F_USER_STACK);
234236
int zero = 0, *val;
235237
val = id.lookup_or_init(&zero, &stack_id);
236-
(*val) = stack_id;
238+
if (val) {
239+
(*val) = stack_id;
240+
}
237241
238242
return 0;
239243
}

tests/lua/test_clang.lua

+3-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,9 @@ int kprobe__finish_task_switch(struct pt_regs *ctx, struct task_struct *prev) {
244244
key.prev_pid = prev->pid;
245245
246246
val = stats.lookup_or_init(&key, &zero);
247-
(*val)++;
247+
if (val) {
248+
(*val)++;
249+
}
248250
return 0;
249251
}
250252
]]}

tests/python/test_clang.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,9 @@ def test_task_switch(self):
397397
key.prev_pid = prev->pid;
398398
399399
val = stats.lookup_or_init(&key, &zero);
400-
(*val)++;
400+
if (val) {
401+
(*val)++;
402+
}
401403
return 0;
402404
}
403405
""")

tests/python/test_license.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ class TestLicense(unittest.TestCase):
4343
bpf_get_current_comm(&(key.comm), 16);
4444
4545
val = counts.lookup_or_init(&key, &zero); // update counter
46-
(*val)++;
46+
if (val) {
47+
(*val)++;
48+
}
4749
return 0;
4850
}
4951
"""

tests/python/test_lru.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ def test_lru_percpu_hash(self):
2727
u32 key=0;
2828
u32 value = 0, *val;
2929
val = stats.lookup_or_init(&key, &value);
30-
*val += 1;
30+
if (val) {
31+
*val += 1;
32+
}
3133
return 0;
3234
}
3335
"""

tests/python/test_percpu.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ def test_u64(self):
3030
u32 key=0;
3131
u64 value = 0, *val;
3232
val = stats.lookup_or_init(&key, &value);
33-
*val += 1;
33+
if (val) {
34+
*val += 1;
35+
}
3436
return 0;
3537
}
3638
"""
@@ -60,7 +62,9 @@ def test_u32(self):
6062
u32 key=0;
6163
u32 value = 0, *val;
6264
val = stats.lookup_or_init(&key, &value);
63-
*val += 1;
65+
if (val) {
66+
*val += 1;
67+
}
6468
return 0;
6569
}
6670
"""
@@ -94,8 +98,10 @@ def test_struct_custom_func(self):
9498
u32 key=0;
9599
counter value = {0,0}, *val;
96100
val = stats.lookup_or_init(&key, &value);
97-
val->c1 += 1;
98-
val->c2 += 1;
101+
if (val) {
102+
val->c1 += 1;
103+
val->c2 += 1;
104+
}
99105
return 0;
100106
}
101107
"""

tests/python/test_stat1.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ int on_packet(struct __sk_buff *skb) {
4848
}
4949
struct IPLeaf zleaf = {0};
5050
struct IPLeaf *leaf = stats.lookup_or_init(&key, &zleaf);
51-
lock_xadd(&leaf->rx_pkts, rx);
52-
lock_xadd(&leaf->tx_pkts, tx);
51+
if (leaf) {
52+
lock_xadd(&leaf->rx_pkts, rx);
53+
lock_xadd(&leaf->tx_pkts, tx);
54+
}
5355
}
5456

5557
EOP:

tests/python/test_trace2.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ BPF_HASH(stats, struct Ptr, struct Counters, 1024);
88
int count_sched(struct pt_regs *ctx) {
99
struct Ptr key = {.ptr = PT_REGS_PARM1(ctx)};
1010
struct Counters zleaf = {0};
11-
stats.lookup_or_init(&key, &zleaf)->stat1++;
11+
struct Counters *val = stats.lookup_or_init(&key, &zleaf);
12+
if (val) {
13+
val->stat1++;
14+
}
1215
return 0;
1316
}

tests/python/test_trace2.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
struct Counters zleaf;
2020
2121
memset(&zleaf, 0, sizeof(zleaf));
22-
stats.lookup_or_init(&key, &zleaf)->stat1++;
22+
struct Counters *val = stats.lookup_or_init(&key, &zleaf);
23+
if (val) {
24+
val->stat1++;
25+
}
2326
return 0;
2427
}
2528
"""

tests/python/test_trace3.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ int probe_blk_update_request(struct pt_regs *ctx) {
4848

4949
u64 zero = 0;
5050
u64 *val = latency.lookup_or_init(&index, &zero);
51-
lock_xadd(val, 1);
51+
if (val) {
52+
lock_xadd(val, 1);
53+
}
5254
return 0;
5355
}

tests/python/test_trace4.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@ def setUp(self):
1414
typedef struct { u64 val; } Val;
1515
BPF_HASH(stats, Key, Val, 3);
1616
int hello(void *ctx) {
17-
stats.lookup_or_init(&(Key){1}, &(Val){0})->val++;
17+
Val *val = stats.lookup_or_init(&(Key){1}, &(Val){0});
18+
if (val) {
19+
val->val++;
20+
}
1821
return 0;
1922
}
2023
int goodbye(void *ctx) {
21-
stats.lookup_or_init(&(Key){2}, &(Val){0})->val++;
24+
Val *val = stats.lookup_or_init(&(Key){2}, &(Val){0});
25+
if (val) {
26+
val->val++;
27+
}
2228
return 0;
2329
}
2430
""")

tests/python/test_trace_maxactive.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,17 @@ def setUp(self):
1414
typedef struct { u64 val; } Val;
1515
BPF_HASH(stats, Key, Val, 3);
1616
int hello(void *ctx) {
17-
stats.lookup_or_init(&(Key){1}, &(Val){0})->val++;
17+
Val *val = stats.lookup_or_init(&(Key){1}, &(Val){0});
18+
if (val) {
19+
val->val++;
20+
}
1821
return 0;
1922
}
2023
int goodbye(void *ctx) {
21-
stats.lookup_or_init(&(Key){2}, &(Val){0})->val++;
24+
Val *val = stats.lookup_or_init(&(Key){2}, &(Val){0});
25+
if (val) {
26+
val->val++;
27+
}
2228
return 0;
2329
}
2430
""")

0 commit comments

Comments
 (0)