Skip to content

Commit

Permalink
libcommon: add uprobe_name() and uprobe_delete()
Browse files Browse the repository at this point in the history
Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Reviewed-by: Nick Alcock <nick.alcock@oracle.com>
  • Loading branch information
kvanhees committed Oct 27, 2022
1 parent b552dbe commit a28e369
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 22 deletions.
84 changes: 62 additions & 22 deletions libcommon/uprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,21 @@ uprobe_decode_name(const char *name)
return decoded;
}

char *
uprobe_name(dev_t dev, ino_t ino, uint64_t addr, int isret)
{
char *name;

if (asprintf(&name, "dt_pid/%c_%llx_%llx_%lx", isret ? 'r' : 'p',
(unsigned long long)dev, (unsigned long long)ino,
(unsigned long)addr) < 0)
return NULL;

return name;
}

/*
* Create a uprobe for a given mapping, address, and spec: the uprobe may be a
* Create a uprobe for a given device, address, and spec: the uprobe may be a
* uretprobe. Return the probe's name as a new dynamically-allocated string, or
* NULL on error. If prv/mod/fun/prb are all set, they are passed down as the
* name of the corresponding DTrace probe.
Expand All @@ -219,16 +232,9 @@ uprobe_create_named(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int i
const char *prv, const char *mod, const char *fun,
const char *prb)
{
int fd;
int rc;
char *name, *args = "";

if (asprintf(&name, "dt_pid/%c_%llx_%llx_%lx",
isret ? 'r' : 'p',
(unsigned long long) dev,
(unsigned long long) ino,
(unsigned long) addr) < 0)
return NULL;
int fd = -1;
int rc = -1;
char *name, *args = NULL;

if (prv && mod && fun && prb) {
char *eprv, *emod, *efun, *eprb;
Expand All @@ -243,8 +249,7 @@ uprobe_create_named(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int i
if (asprintf(&args, "P%s=\\1 M%s=\\2 F%s=\\3 N%s=\\4",
eprv, emod, efun, eprb) < 0)
failed = 1;
}
else
} else
failed = 1;

free(eprv);
Expand All @@ -256,17 +261,24 @@ uprobe_create_named(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int i
return NULL;
}

name = uprobe_name(dev, ino, addr, isret);
if (!name)
goto out;

/* Add the uprobe. */
fd = open(TRACEFS "uprobe_events", O_WRONLY | O_APPEND);
if (fd != -1) {
rc = dprintf(fd, "%c:%s %s %s\n", isret ? 'r' : 'p',
name, spec, args);
if (fd == -1)
goto out;

/* TODO: error reporting, probably via a callback */
close(fd);
}
rc = dprintf(fd, "%c:%s %s %s\n", isret ? 'r' : 'p', name, spec,
args ? args : "");

if (fd == -1 || rc == -1) {
out:
if (fd == -1)
close(fd);
free(args);
if (rc < 0) {
free(name);
return NULL;
}

Expand All @@ -282,8 +294,8 @@ uprobe_create_named(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int i
char *
uprobe_create(dev_t dev, ino_t ino, uint64_t addr, const char *spec, int isret)
{
return uprobe_create_named(dev, ino, addr, spec, isret,
NULL, NULL, NULL, NULL);
return uprobe_create_named(dev, ino, addr, spec, isret,
NULL, NULL, NULL, NULL);
}

/*
Expand All @@ -308,3 +320,31 @@ uprobe_create_from_addr(pid_t pid, uint64_t addr, const char *prv,
free(spec);
return name;
}

/*
* Destroy a uprobe for a given device, address, and spec.
*/
int
uprobe_delete(dev_t dev, ino_t ino, uint64_t addr, int isret)
{
int fd = -1;
int rc = -1;
char *name;

name = uprobe_name(dev, ino, addr, isret);
if (!name)
goto out;

fd = open(TRACEFS "uprobe_events", O_WRONLY | O_APPEND);
if (fd == -1)
goto out;

rc = dprintf(fd, "-:%s\n", name);

out:
if (fd != -1)
close(fd);
free(name);

return rc < 0 ? -1 : 0;
}
2 changes: 2 additions & 0 deletions libcommon/uprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

extern char *uprobe_spec_by_addr(pid_t pid, ps_prochandle *P, uint64_t addr,
prmap_t *mapp);
extern char *uprobe_name(dev_t dev, ino_t ino, uint64_t addr, int isret);
extern char *uprobe_create_named(dev_t dev, ino_t ino, uint64_t addr,
const char *spec, int isret, const char *prv,
const char *mod, const char *fun,
Expand All @@ -24,6 +25,7 @@ extern char *uprobe_create(dev_t dev, ino_t ino, uint64_t addr, const char *spec
extern char *uprobe_create_from_addr(pid_t pid, uint64_t addr, const char *prv,
const char *mod, const char *fun,
const char *prb);
extern int uprobe_delete(dev_t dev, ino_t ino, uint64_t addr, int isret);
extern char *uprobe_encode_name(const char *);
extern char *uprobe_decode_name(const char *);

Expand Down

0 comments on commit a28e369

Please sign in to comment.