-
Notifications
You must be signed in to change notification settings - Fork 937
Correctly check if profiler is preloaded #1374
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
Conversation
src/os_linux.cpp
Outdated
|
||
if (info->dlpi_name == NULL) { | ||
return 0; | ||
} else if (strcmp(info->dlpi_name, current_info.dli_fname) == 0) { |
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.
Can we compare base address (dli_fbase) instead?
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 will need to check on this
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.
have been updated here 78edb2a
From the testing I did it looks like it does the trick
src/os_macos.cpp
Outdated
continue; | ||
} else if (strcmp(image_name, current_info.dli_fname) == 0) { | ||
return true; | ||
}else if(strcmp(image_name, sigaction_info.dli_fname) == 0) { |
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.
Formatting
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.
handled here 78edb2a
src/os_linux.cpp
Outdated
} | ||
|
||
Dl_info sigaction_info; | ||
if (dladdr((const void*)sigaction, &sigaction_info) == 0 || sigaction_info.dli_fname == NULL) { |
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.
Just wondering why sigaction
? Not the most obvious function in libc - may confuse someone who sees this for the first time. A short comment describing the idea of checkPreloaded
would be useful anyway.
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 wanted to avoid typical functions that some other developer might interpose/preload as that would effect the accuracy of the check
For example dlopen
on Linux dladdr
will resolve to the async-profiler when it's preloaded
=> I wanted to avoid using functions that we patch/preload to keep the check consistent for all cases
I will add a comment for describing what the function does
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.
doc added here 78edb2a
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.
Still, sigaction
is a bad choice. Not only because it's some random unrelated function, but also because it does not meet the criteria you've mentioned:
I wanted to avoid typical functions that some other developer might interpose/preload
It's not uncommon to intercept sigaction
for signal chaining purposes. A prominent example is JDK's libjsig
library.
I'd choose some basic function like exit
.
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.
updated here 6e283d6
src/zInit.cpp
Outdated
} | ||
|
||
if (!checkJvmLoaded()) { | ||
if (!checkJvmLoaded() && OS::checkPreloaded()) { |
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.
A minor thing, but I'd propose to move this check after ASPROF_COMMAND
check, since using async-profiler through native API will be a common thing, while LD_PRELOAD
is used rarely and mostly for ad-hoc profiling only.
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.
handled here 78edb2a
…iable, check image address for linux
src/os_linux.cpp
Outdated
if (info->dlpi_name == NULL) { | ||
return 0; |
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.
Redundant check?
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.
removed 6e283d6
src/os_linux.cpp
Outdated
|
||
// Find async-profiler shared objects | ||
Dl_info current_info; | ||
if (dladdr((const void*)OS::checkPreloaded, ¤t_info) == 0 || current_info.dli_fname == NULL) { |
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.
Is comparing dli_fname
really necessary?
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 will update it to check dli_fbase
instead
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.
updated here 6e283d6
src/os_linux.cpp
Outdated
} | ||
|
||
Dl_info sigaction_info; | ||
if (dladdr((const void*)sigaction, &sigaction_info) == 0 || sigaction_info.dli_fname == NULL) { |
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.
Still, sigaction
is a bad choice. Not only because it's some random unrelated function, but also because it does not meet the criteria you've mentioned:
I wanted to avoid typical functions that some other developer might interpose/preload
It's not uncommon to intercept sigaction
for signal chaining purposes. A prominent example is JDK's libjsig
library.
I'd choose some basic function like exit
.
src/os_macos.cpp
Outdated
|
||
uint32_t images = _dyld_image_count(); | ||
for (uint32_t i = 0; i < images; i++) { | ||
const char* image_name = _dyld_get_image_name(i); |
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.
Is it possible to use base address on macOS, similarly to how you do this on Linux?
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 did some double checking, yes we can check against _dyld_get_image_header
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.
Updated here 6e283d6
src/os_linux.cpp
Outdated
|
||
// Find async-profiler shared objects | ||
Dl_info current_info; | ||
if (dladdr((const void*)OS::checkPreloaded, ¤t_info) == 0 || current_info.dli_fbase == NULL) { |
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 would dli_fbase
be NULL
? Is it even possible?
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.
yeah it shouldn't be needed, will remove it
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.
src/os_macos.cpp
Outdated
return false; | ||
} | ||
|
||
// Find async-profiler shared objects |
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.
object (singular)?
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.
src/os_macos.cpp
Outdated
} | ||
|
||
// Find async-profiler shared objects | ||
Dl_info current_info; |
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.
current_info
and exist_info
sound a bit vague.
What about lib_async_profiler
(or maybe libprofiler
) and libc
?
Then conditions like if (image_base == libc.dli_fbase)
will be self-descriptive.
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 will use libprofiler
& libc
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.
Updated here 486dc9d
Description
Add proper checking to validate that the profiler was preloaded as to avoid false starts
Currently if
ASPROF_COMMAND
env variable is defined any dlopen on the profiler will cause it to start which means the profiler might start with incorrect profiling optionsFurthermore in this case async-profiler will assume that preload hooks exists which might not be true, which will to incomplete profiling by the profiler
Related issues
N/A
Motivation and context
Avoid false early starts for the async-profiler
How has this been tested?
New test added
make test
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.