Add bcc_usdt_enable_fully_specified_probe to avoid usdt provider collisions
diff --git a/src/cc/bcc_usdt.h b/src/cc/bcc_usdt.h
index a031bc6..0c54809 100644
--- a/src/cc/bcc_usdt.h
+++ b/src/cc/bcc_usdt.h
@@ -70,6 +70,8 @@
struct bcc_usdt_argument *argument);
int bcc_usdt_enable_probe(void *, const char *, const char *);
+#define BCC_USDT_HAS_FULLY_SPECIFIED_PROBE
+int bcc_usdt_enable_fully_specified_probe(void *, const char *, const char *, const char *);
const char *bcc_usdt_genargs(void **ctx_array, int len);
const char *bcc_usdt_get_probe_argctype(
void *ctx, const char* probe_name, const int arg_index
diff --git a/src/cc/usdt.h b/src/cc/usdt.h
index 406cfd5..f746d03 100644
--- a/src/cc/usdt.h
+++ b/src/cc/usdt.h
@@ -280,6 +280,7 @@
Probe *get(int pos) { return probes_[pos].get(); }
bool enable_probe(const std::string &probe_name, const std::string &fn_name);
+ bool enable_probe(const std::string &provider_name, const std::string &probe_name, const std::string &fn_name);
typedef void (*each_cb)(struct bcc_usdt *);
void each(each_cb callback);
diff --git a/src/cc/usdt/usdt.cc b/src/cc/usdt/usdt.cc
index c91faa0..5f78509 100644
--- a/src/cc/usdt/usdt.cc
+++ b/src/cc/usdt/usdt.cc
@@ -295,24 +295,46 @@
bool Context::enable_probe(const std::string &probe_name,
const std::string &fn_name) {
+ return enable_probe("", probe_name, fn_name);
+}
+
+bool Context::enable_probe(const std::string &provider_name,
+ const std::string &probe_name,
+ const std::string &fn_name) {
if (pid_stat_ && pid_stat_->is_stale())
return false;
- // FIXME: we may have issues here if the context has two same probes's
- // but different providers. For example, libc:setjmp and rtld:setjmp,
- // libc:lll_futex_wait and rtld:lll_futex_wait.
+ unsigned int matches = 0;
Probe *found_probe = nullptr;
for (auto &p : probes_) {
if (p->name_ == probe_name) {
- if (found_probe != nullptr) {
- fprintf(stderr, "Two same-name probes (%s) but different providers\n",
- probe_name.c_str());
- return false;
+ if (found_probe == nullptr && provider_name == "")
+ {
+ found_probe = p.get();
+ matches++;
}
- found_probe = p.get();
+ else if (found_probe != nullptr && provider_name == "")
+ {
+ fprintf(stderr, "Found duplicate provider (%s) for underspecified probe (%s)\n",
+ p->provider().c_str(), p->name().c_str());
+ matches++;
+ } else if (provider_name != "" && p->provider() == provider_name)
+ {
+ found_probe = p.get();
+ matches++;
+ }
}
}
+ if (matches > 1) {
+ fprintf(stderr, "Found %i duplicate providers for underpecified probe (%s)\n",
+ matches, fn_name.c_str());
+ return false;
+ } else if(matches < 1) {
+ fprintf(stderr, "No matches found for probe (%s)\n", fn_name.c_str());
+ return false;
+ }
+
if (found_probe != nullptr)
return found_probe->enable(fn_name);
@@ -448,6 +470,14 @@
return ctx->enable_probe(probe_name, fn_name) ? 0 : -1;
}
+int bcc_usdt_enable_fully_specified_probe(void *usdt,
+ const char *provider_name,
+ const char *probe_name,
+ const char *fn_name) {
+ USDT::Context *ctx = static_cast<USDT::Context *>(usdt);
+ return ctx->enable_probe(provider_name, probe_name, fn_name) ? 0 : -1;
+}
+
const char *bcc_usdt_genargs(void **usdt_array, int len) {
static std::string storage_;
std::ostringstream stream;