-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[uprobe] support for pid targeting for shared libs #2830
Conversation
Note: I looked into making a runtime test for this but it seems pretty tricky in that you'd have to run two programs that use the same shared library and assert you weren't getting samples for one of them. |
I'm a bit conflicted about this feature. I can definitely see it being useful to retrofit PID-filtering into existing scripts, but I feel like the better way of doing this would be to have the script include a PID predicate itself:
If we sort out script-level argument parsing properly then this could be made more powerful by filtering on multiple PIDs, e.g. |
Seems reasonable to put in at least until we do have proper argument parsing support though. This new feature applies to all uprobes, not just on shared libs, right? |
It's definitely more powerful doing it this way but I think this change is (at least for me) about matching expected behavior. Because we already support pid filtering for USDTs and uprobes/uretprobes (when there is a wildcard involved) I feel like it makes sense to do this as well for all uprobe/uretprobe invocations.
Yeah I believe so.
Maybe I'm confused but I think the problem is not so much attaching to the right pid but testing that we're not attaching to the other pids (or maybe you're saying I should write a NOT_EXPECT predicate). I could write a simple test that passing a pid argument doesn't affect attaching, which ensures we're not breaking existing behavior, but is not testing the new behavior. Maybe an example would help my brain 🧠 |
Yep, makes sense. For the tests, I was imagining something like this:
Although I don't know how well the test framework will cope with this, particularly getting the PID of a process. |
206a5e4
to
3be88e5
Compare
@ajor Thanks for the suggestion on the test. I got around the limitation of having multiple BEFOREs but needing the BEFORE_PID by just spinning up a program that forks. I confirmed that this test fails on master. |
3be88e5
to
c156b30
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we sort out script-level argument parsing properly then this could be made more powerful by filtering on multiple PIDs
It's definitely more powerful doing it this way but I think this change is (at least for me) about matching expected behavior. Because we already support pid filtering for USDTs and uprobes/uretprobes (when there is a wildcard involved) I feel like it makes sense to do this as well for all uprobe/uretprobe invocations.
Agreed with @jordalgo here, this is the expected behaviour to me. I don't see a situation where I would want to attach binary uprobes to a PID but attach library uprobes system-wide.
Just a couple of remarks, otherwise looks good, thanks!
src/attached_probe.cpp
Outdated
@@ -191,7 +191,7 @@ AttachedProbe::AttachedProbe(Probe &probe, | |||
// If BPF_PROG_TYPE_RAW_TRACEPOINT is available, no need to attach prog | |||
// to anything -- we will simply BPF_PROG_RUN it | |||
if (!feature.has_raw_tp_special()) | |||
attach_uprobe(safe_mode); | |||
attach_uprobe(0, safe_mode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this is correct. IIUC, we use process' PID in this case, set in bpftrace.cpp:1090. This should probably use the same approach.
tests/testprogs/uprobe_fork_loop.c
Outdated
if (fork() == 0) | ||
{ | ||
spin(); | ||
} | ||
else | ||
{ | ||
spin(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spin()
is run in both the true and false cases - can the if-statement be removed entirely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. It can. This is what I get from just copying from the interwebs
c156b30
to
6eb2184
Compare
Updated based on comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just two nits (see the CodeQL warnings).
6eb2184
to
30c49e7
Compare
Lint fixes. |
src/attached_probe.h
Outdated
@@ -30,7 +30,8 @@ class AttachedProbe | |||
BpfProgram &&prog, | |||
int pid, | |||
BPFfeature &feature, | |||
BTF &btf); | |||
BTF &btf, | |||
bool safe_mode = false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why default to non safe mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This default isn't being used by anything checking safe_mode so fine to make it default to true.
|
||
int main(int argc __attribute__((unused)), char **argv __attribute__((unused))) | ||
{ | ||
pid_t p = fork(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we wait for the child? Otherwise zombie process right
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want them to be running at the same time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah. Thought spin()
had finite iterations. If we rely on runtime test runner to kill the process group this should be fine
30c49e7
to
3cf96ca
Compare
make |
This adds support for specifying the pid even when targeting a uprobe/uretprobe in a library shared by multiple pids. Example: ``` sudo bpftrace -p 1899508 -e 'uprobe:libc:getaddrinfo { print((comm, pid)); } ``` [Issue 2817](bpftrace#2817)
3cf96ca
to
c83afea
Compare
This adds support for specifying the pid even when targeting a uprobe/uretprobe in a library shared by multiple pids.
Example:
Issue 2817
Checklist
man/adoc/bpftrace.adoc
and if needed indocs/reference_guide.md
CHANGELOG.md