Skip to content

Commit

Permalink
usdt: permit to enable probes from a pid and a particular binary
Browse files Browse the repository at this point in the history
Currently, for usdt, the commands where both a pid and a binary path
are specified are not well supported. For example,
```
funccount -p <pid> 'u:<binary_path>:probe'
```
will count `probe` occurances for all binary paths in `pid`, not just
`<binary_path>`. The command
```
argdist -p <pid> 'u:<binary_path>:probe():s64:arg1'
```
will also count `probe` occurances for all binary paths in `pid`
with my previous patch.

Furthermore, suppose user want to trace linker `setjmp` probe point
with command
```
trace.py -p <pid> 'u:/usr/lib64/ld-2.17.so:setjmp'
```
Without my previous patch, user will have incorrect results as both
`libc:setjmp` and `rtld:setjmp` exists and the bcc just picks the first
one which is `libc:setjmp`. My last patch will cause `enable_probe`
failures if in the same usdt context, two probes have the same
probe_name but different provider name.

To fix all these issues, this patch passes additional binary path
to the pid-based usdt context, so that only probes from that particular
binary will be added to the context. This solved all the above
mentioned issues.

Signed-off-by: Yonghong Song <yhs@fb.com>
  • Loading branch information
yonghong-song committed Jan 12, 2018
1 parent 2489457 commit fead16a
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/cc/bcc_usdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extern "C" {

#include <stdint.h>

void *bcc_usdt_new_frompid(int pid);
void *bcc_usdt_new_frompid(int pid, const char *path);
void *bcc_usdt_new_frompath(const char *path);
void bcc_usdt_close(void *usdt);

Expand Down
2 changes: 1 addition & 1 deletion src/cc/link_all.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace {
if (::getenv("bar") != (char *)-1)
return;

(void)bcc_usdt_new_frompid(-1);
(void)bcc_usdt_new_frompid(-1, nullptr);
(void)bcc_usdt_new_frompath(nullptr);
(void)bcc_usdt_close(nullptr);
}
Expand Down
1 change: 1 addition & 0 deletions src/cc/usdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ class Context {
public:
Context(const std::string &bin_path);
Context(int pid);
Context(int pid, const std::string &bin_path);
~Context();

optional<int> pid() const { return pid_; }
Expand Down
25 changes: 23 additions & 2 deletions src/cc/usdt/usdt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,22 @@ Context::Context(int pid) : pid_(pid), pid_stat_(pid),
probe->finalize_locations();
}

Context::Context(int pid, const std::string &bin_path)
: pid_(pid), pid_stat_(pid),
mount_ns_instance_(new ProcMountNS(pid)), loaded_(false) {
std::string full_path = resolve_bin_path(bin_path);
if (!full_path.empty()) {
if (bcc_elf_foreach_usdt(full_path.c_str(), _each_probe, this) == 0) {
cmd_bin_path_ = ebpf::get_pid_exe(pid);
if (cmd_bin_path_.empty())
return;
loaded_ = true;
}
}
for (const auto &probe : probes_)
probe->finalize_locations();
}

Context::~Context() {
if (pid_stat_ && !pid_stat_->is_stale()) {
for (auto &p : probes_) p->disable();
Expand All @@ -374,8 +390,13 @@ Context::~Context() {

extern "C" {

void *bcc_usdt_new_frompid(int pid) {
USDT::Context *ctx = new USDT::Context(pid);
void *bcc_usdt_new_frompid(int pid, const char *path) {
USDT::Context *ctx;

if (!path)
ctx = new USDT::Context(pid);
else
ctx = new USDT::Context(pid, path);
if (!ctx->loaded()) {
delete ctx;
return nullptr;
Expand Down
2 changes: 1 addition & 1 deletion src/python/bcc/libbcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ class bcc_symbol_option(ct.Structure):
lib.bcc_symcache_refresh.argtypes = [ct.c_void_p]

lib.bcc_usdt_new_frompid.restype = ct.c_void_p
lib.bcc_usdt_new_frompid.argtypes = [ct.c_int]
lib.bcc_usdt_new_frompid.argtypes = [ct.c_int, ct.c_char_p]

lib.bcc_usdt_new_frompath.restype = ct.c_void_p
lib.bcc_usdt_new_frompath.argtypes = [ct.c_char_p]
Expand Down
5 changes: 4 additions & 1 deletion src/python/bcc/usdt.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,10 @@ class USDT(object):
def __init__(self, pid=None, path=None):
if pid and pid != -1:
self.pid = pid
self.context = lib.bcc_usdt_new_frompid(pid)
if path:
self.context = lib.bcc_usdt_new_frompid(pid, path.encode('ascii'))
else:
self.context = lib.bcc_usdt_new_frompid(pid, ct.c_char_p(0))
if self.context == None:
raise USDTException("USDT failed to instrument PID %d" % pid)
elif path:
Expand Down

0 comments on commit fead16a

Please sign in to comment.