The code generated by the USDT helpers for reading probe arguments
occasionally caused a verifier error due to a construct similar to
the following:
```
switch (ctx->ip) {
case 0xaaaa: *dest = ctx->cx; break;
case 0xbbbb: *dest = ctx->dx; break;
}
```
This would generate an instruction sequence that attempts to access
ctx through an offset that is not statically known, which confuses
the verifier. This was reported in #751, #829, and #1133, and likely
seen by others as well.
The workaround, suggested by @yonghong-song, is to force memory
writes by using the volatile modifier, which precludes this specific
optimization.
Resolves #751, #829, #1133.
for (size_t arg_n = 0; arg_n < arg_count; ++arg_n) {
std::string ctype = largest_arg_type(arg_n);
- std::string cptr = tfm::format("*((%s *)dest)", ctype);
+ std::string cptr = tfm::format("*((volatile %s *)dest)", ctype);
tfm::format(stream,
- "static inline int _bpf_readarg_%s_%d("
+ "static __always_inline int _bpf_readarg_%s_%d("
"struct pt_regs *ctx, void *dest, size_t len) {\n"
" if (len != sizeof(%s)) return -1;\n",
attached_to_.value(), arg_n + 1, ctype);