Skip to content

Commit

Permalink
codegen: Fix segfault of CodegenLLVM::generateProbe()
Browse files Browse the repository at this point in the history
If it is dummy, then the visit() operation should not be executed. For
example, on aarch64, there is no syscalls:sys_{enter,exit}_open
tracepoint, however, opensnoop.bt tool will try to attch them and visit
args's field. We expect to get a warning, but instead we get a segmentation
fault. As follows:

    $ sudo gdb bpftrace
    ...
    (gdb) set args opensnoop.bt
    (gdb) r
    opensnoop.bt:22-24: WARNING: tracepoint not found: syscalls:sys_enter_open
    opensnoop.bt:28-30: WARNING: tracepoint not found: syscalls:sys_exit_open

    Thread 1 "bpftrace" received signal SIGSEGV, Segmentation fault.
    0x000000000052bbd8 in __gnu_cxx::__normal_iterator<bpftrace::Field const*, std::vector<bpftrace::Field, std::allocator<bpftrace::Field> > >::__normal_iterator (this=0xffffffffb0b8, __i=<error reading variable: Cannot access memory at address 0x10>)
        at /usr/include/c  /14/bits/stl_iterator.h:1068
    1068              : _M_current(__i) { }
    (gdb) bt
    #0  0x000000000052bbd8 in __gnu_cxx::__normal_iterator<bpftrace::Field const*, std::vector<bpftrace::Field, std::allocator<bpftrace::Field> > >::__normal_iterator (this=0xffffffffb0b8,
        __i=<error reading variable: Cannot access memory at address 0x10>) at /usr/include/c  /14/bits/stl_iterator.h:1068
    #1  0x0000000000525bdc in std::vector<bpftrace::Field, std::allocator<bpftrace::Field> >::begin (this=0x10)
        at /usr/include/c  /14/bits/stl_vector.h:884
    bpftrace#2  0x000000000059ce8c in bpftrace::Struct::GetField (this=0x0, name="filename")
        at /home/rongtao/Git/bpftrace/bpftrace/src/struct.cpp:131
    bpftrace#3  0x00000000005a70a0 in bpftrace::SizedType::GetField (this=0xe9b998, name="filename")
        at /home/rongtao/Git/bpftrace/bpftrace/src/types.cpp:538
    bpftrace#4  0x00000000007c7178 in bpftrace::ast::CodegenLLVM::visit (this=0xffffffffc650, acc=...)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:1973
    bpftrace#5  0x0000000000847db0 in bpftrace::ast::FieldAccess::accept (this=0xe9be30, v=...)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/ast.cpp:31
    bpftrace#6  0x00000000007d2404 in bpftrace::ast::CodegenLLVM::accept (this=0xffffffffc650, node=0xe9be30)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:3778
    bpftrace#7  0x00000000007c8bec in bpftrace::ast::CodegenLLVM::visit (this=0xffffffffc650, assignment=...)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:2218
    bpftrace#8  0x0000000000847eb4 in bpftrace::ast::AssignMapStatement::accept (this=0xffffe4429250, v=...)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/ast.cpp:36
    bpftrace#9  0x00000000007d2404 in bpftrace::ast::CodegenLLVM::accept (this=0xffffffffc650, node=0xffffe4429250)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:3778
    bpftrace#10 0x00000000007ca4c4 in bpftrace::ast::CodegenLLVM::generateProbe (this=0xffffffffc650, probe=..., full_func_id="dummy",
        name="dummy", func_type=0xff2b50, usdt_location_index=std::optional [no contained value], dummy=true)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:2539
    bpftrace#11 0x00000000007cb4e4 in bpftrace::ast::CodegenLLVM::visit (this=0xffffffffc650, probe=...)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:2734
    bpftrace#12 0x00000000008480f0 in bpftrace::ast::Probe::accept (this=0xffffe4427650, v=...)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/ast.cpp:47
    bpftrace#13 0x00000000007d2404 in bpftrace::ast::CodegenLLVM::accept (this=0xffffffffc650, node=0xffffe4427650)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:3778
    bpftrace#14 0x00000000007cb7a4 in bpftrace::ast::CodegenLLVM::visit (this=0xffffffffc650, program=...)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:2752
    bpftrace#15 0x000000000084818c in bpftrace::ast::Program::accept (this=0xe90f50, v=...)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/ast.cpp:50
    bpftrace#16 0x00000000007d2404 in bpftrace::ast::CodegenLLVM::accept (this=0xffffffffc650, node=0xe90f50)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:3778
    bpftrace#17 0x00000000007d03fc in bpftrace::ast::CodegenLLVM::generate_ir (this=0xffffffffc650)
        at /home/rongtao/Git/bpftrace/bpftrace/src/ast/passes/codegen_llvm.cpp:3450
    bpftrace#18 0x0000000000478138 in main (argc=2, argv=0xfffffffff4c8) at /home/rongtao/Git/bpftrace/bpftrace/src/main.cpp:898

We can simplify opensnoop.bt to:

    tracepoint:syscalls:sys_enter_open_not_exist,
    tracepoint:syscalls:sys_enter_openat
    {
        @ = args.filename;
    }

This will produce the following error:

    stdin:1:1-45: WARNING: tracepoint not found: syscalls:sys_enter_open_not_exist
    tracepoint:syscalls:sys_enter_open_not_exist,tracepoint:syscalls:sys_enter_openat {@ = args.filename;}
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Segmentation fault

We need to generate the dummy probe only for cases when none of the probe
attach points exists.

Link: bpftrace#3274
Signed-off-by: Viktor Malik <[email protected]>
Signed-off-by: Rong Tao <[email protected]>
  • Loading branch information
Rtoax authored and viktormalik committed Jul 2, 2024
1 parent 7b9b4e9 commit ca1b216
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 29,8 @@ and this project adheres to
- Remove the `-dd` CLI option
- [#3203](https://github.com/bpftrace/bpftrace/pull/3203)
#### Fixed
- Fix segfault for multi-tracepoint probes
- [#3274](https://github.com/bpftrace/bpftrace/pull/3274)
#### Security
#### Docs
- Remove mention of unsupported character literals
Expand Down
9 changes: 6 additions & 3 deletions src/ast/passes/codegen_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2710,6 2710,7 @@ void CodegenLLVM::visit(Probe &probe)
// We begin by saving state that gets changed by the codegen pass, so we
// can restore it for the next pass (printf_id_, time_id_).
auto reset_ids = async_ids_.create_reset_ids();
bool generated = false;
for (auto *attach_point : *probe.attach_points) {
reset_ids();
current_attach_point_ = attach_point;
Expand Down Expand Up @@ -2739,16 2740,18 @@ void CodegenLLVM::visit(Probe &probe)

auto match_ap = attach_point->create_expansion_copy(match);
add_probe(match_ap, probe, match, func_type);
}
if (matches.empty()) {
generateProbe(probe, "dummy", "dummy", func_type, std::nullopt, true);
generated = true;
}
} else {
if (probe.index() == 0)
probe.set_index(getNextIndexForProbe());
add_probe(*attach_point, probe, attach_point->name(), func_type);
generated = true;
}
}
if (!generated) {
generateProbe(probe, "dummy", "dummy", func_type, std::nullopt, true);
}

current_attach_point_ = nullptr;
}
Expand Down

0 comments on commit ca1b216

Please sign in to comment.