Skip to content
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

Add --usdt-file-activation to activate USDT semaphores by filename #1317

Merged
merged 7 commits into from
May 15, 2020

Conversation

danobi
Copy link
Member

@danobi danobi commented May 5, 2020

This PR implements USDT semaphore probe activation. Previously, you had
to pass in -p $PID or -c $CMD to activate usdt semaphores on a process.
This has the limitation of single binaries. It's also difficult to make work in a
distributed tracing environment where you don't know the PIDs beforehand are
attaching to running processes.

Checklist
  • Language changes are updated in docs/reference_guide.md
  • User-visible and non-trivial changes updated in CHANGELOG.md

@danobi danobi requested a review from fbs May 5, 2020 23:38
@danobi
Copy link
Member Author

danobi commented May 5, 2020

cc @dalehamel

@danobi
Copy link
Member Author

danobi commented May 6, 2020

Hmm clang format is failing but I don't think I touched those files. Gonna ignore it and hope it goes away. Otherwise I'll put up another PR later to format over it.

@dalehamel
Copy link
Contributor

Thanks for this will take a look soon @danobi

@@ -192,6 +195,7 @@ int main(int argc, char *argv[])
option long_options[] = {
option{ "help", no_argument, nullptr, 'h' },
option{ "version", no_argument, nullptr, 'V' },
option{ "usdt-file-activation", no_argument, nullptr, '$' },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ seems like a weird flag, or it is a special thing in getopt long?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only used for the switch/case. No short option for this flag.

src/bpftrace.cpp Outdated Show resolved Hide resolved
src/bpftrace.cpp Outdated Show resolved Hide resolved
src/bpftrace.cpp Outdated Show resolved Hide resolved
src/bpftrace.cpp Outdated Show resolved Hide resolved
@danobi danobi force-pushed the usdt_file_activation branch 2 times, most recently from 8b868d9 to c4408a8 Compare May 7, 2020 19:47
@danobi
Copy link
Member Author

danobi commented May 7, 2020

I added another runtime tests for multi-process too

@danobi
Copy link
Member Author

danobi commented May 13, 2020

Any objections?

// with execute permission. If found, we will try to attach to each
// process we find.
glob_t globbuf;
if (::glob("/proc/[0-9]*/maps", GLOB_NOSORT, nullptr, &globbuf))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how this will work for containers?

If we have different process namespaces, they will have their own view of /proc, so there are probably edge cases with a different process / mount namespace that we need to think through.

Provided bpftrace is in the same process / mount namespace you want to target though, this should work. If bpftrace runs from the root pid namespace i think this will be fine, but we may want to document this quick

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So if bpftrace runs in root host I believe all processes running in containers can be activated. If bpftrace runs inside a pid/mount namespace then only the processes visible inside that container will be activated. This seems like fairly desirable and expected behavior.

Let me confirm that this is the behavior.

@dalehamel
Copy link
Contributor

makes sense, i added a note about mount namespaces but that can probably be solved later (and there are already lots of issues with USDT and separate mount/process namespaces, so people are probably used to quirks here already)

@danobi
Copy link
Member Author

danobi commented May 14, 2020

I added another runtime test for running inside pid + mount namespaces. I also added a note in the documentation about how doing funny things w/ private mount namespaces and bind mounts can bread usdt file activation. Lots of quirks indeed.

@danobi
Copy link
Member Author

danobi commented May 15, 2020

Removed the container test. Worked on all my machines but fails in CI. No idea.

@dalehamel
Copy link
Contributor

There are actions available to allow ssh in to GitHub actions, maybe that can provide some insight into the failure?

It might also be because actions runs in docker maybe? Can’t remember if it runs with host pid, I would have assumed so. (Checking from phone sorry)

@danobi
Copy link
Member Author

danobi commented May 15, 2020

I'll put up another PR with the additional test and debug there

@danobi danobi merged commit a3170d1 into bpftrace:master May 15, 2020
danobi added a commit to danobi/bpftrace that referenced this pull request May 15, 2020
danobi added a commit to danobi/bcc that referenced this pull request Jun 5, 2020
While debugging a high memory consumption issue in bpftrace, I noticed
that a USDT::Context object can take ~10M per instance [0]. Along with
the new --usdt-file-activation feature in bpftrace
( bpftrace/bpftrace#1317 ), bpftrace can
potentially hold onto many dozens of USDT:Context instances, causing
memory issues.

While reducing the amount of memory USDT::Context uses is one option,
we can potentially side step it by allowing the usdt semaphore count to
be set independently. Before, the only way to increment the count (by 1)
is to call bcc_usdt_enable*(). bcc_usdt_enable*() has checks that limit
it to a single increment per context. The only way to decrement the
count is by calling bcc_usdt_close() which naturally only allows for
one decrement.

With independent semaphore helpers, we can avoid holding onto a
USDT::Context instance for the lifetime of the tracing session. We can
simply:

1. create a USDT::Context
2. increment the semaphore count for the probe we care about
3. destroy the USDT::Context
4. repeat 1-3 for all probes we want to attach to
5. do our tracing
6. create a USDT::Context for the probe we care about
7. decrement the semaphore count
8. destroy the USDT::Context
9. repeat 6-8 for all the probes we're attached to

This approach also has the benefit of 1 USDT::Context instance being
alive at a time which can help keep memory high watermark low.

[0]: Through gdb single stepping and /proc/pid/status. Exact process is
not described here b/c memory usage probably varies based on tracee
binary.
yonghong-song pushed a commit to iovisor/bcc that referenced this pull request Jun 5, 2020
While debugging a high memory consumption issue in bpftrace, I noticed
that a USDT::Context object can take ~10M per instance [0]. Along with
the new --usdt-file-activation feature in bpftrace
( bpftrace/bpftrace#1317 ), bpftrace can
potentially hold onto many dozens of USDT:Context instances, causing
memory issues.

While reducing the amount of memory USDT::Context uses is one option,
we can potentially side step it by allowing the usdt semaphore count to
be set independently. Before, the only way to increment the count (by 1)
is to call bcc_usdt_enable*(). bcc_usdt_enable*() has checks that limit
it to a single increment per context. The only way to decrement the
count is by calling bcc_usdt_close() which naturally only allows for
one decrement.

With independent semaphore helpers, we can avoid holding onto a
USDT::Context instance for the lifetime of the tracing session. We can
simply:

1. create a USDT::Context
2. increment the semaphore count for the probe we care about
3. destroy the USDT::Context
4. repeat 1-3 for all probes we want to attach to
5. do our tracing
6. create a USDT::Context for the probe we care about
7. decrement the semaphore count
8. destroy the USDT::Context
9. repeat 6-8 for all the probes we're attached to

This approach also has the benefit of 1 USDT::Context instance being
alive at a time which can help keep memory high watermark low.

[0]: Through gdb single stepping and /proc/pid/status. Exact process is
not described here b/c memory usage probably varies based on tracee
binary.
CrackerCat pushed a commit to CrackerCat/bcc that referenced this pull request Jul 31, 2024
While debugging a high memory consumption issue in bpftrace, I noticed
that a USDT::Context object can take ~10M per instance [0]. Along with
the new --usdt-file-activation feature in bpftrace
( bpftrace/bpftrace#1317 ), bpftrace can
potentially hold onto many dozens of USDT:Context instances, causing
memory issues.

While reducing the amount of memory USDT::Context uses is one option,
we can potentially side step it by allowing the usdt semaphore count to
be set independently. Before, the only way to increment the count (by 1)
is to call bcc_usdt_enable*(). bcc_usdt_enable*() has checks that limit
it to a single increment per context. The only way to decrement the
count is by calling bcc_usdt_close() which naturally only allows for
one decrement.

With independent semaphore helpers, we can avoid holding onto a
USDT::Context instance for the lifetime of the tracing session. We can
simply:

1. create a USDT::Context
2. increment the semaphore count for the probe we care about
3. destroy the USDT::Context
4. repeat 1-3 for all probes we want to attach to
5. do our tracing
6. create a USDT::Context for the probe we care about
7. decrement the semaphore count
8. destroy the USDT::Context
9. repeat 6-8 for all the probes we're attached to

This approach also has the benefit of 1 USDT::Context instance being
alive at a time which can help keep memory high watermark low.

[0]: Through gdb single stepping and /proc/pid/status. Exact process is
not described here b/c memory usage probably varies based on tracee
binary.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants