-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
Disable "UseOdrIndicator" ASan instrumentation mode by default. #35074
Conversation
@swift-ci Please test |
@swift-ci Please smoke test |
Build failed |
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 am happy with this patch with one small ask (check that we get an unused warning without ASan) and one small nit (code for checking existence of boolean command line option).
This patch does the following two things:
- Add a Swift driver frontend flag to allow opting into ASan's UseOdrIndicator.
- Switch the default behavior from
UseOdrIndicator=true
toUseOdrIndicator=false
.
I agree with Dan's reasoning that it being true for Swift was most likely just an oversight and aligning it with clang's behavior seems like the right thing to do.
@kubamracek: do you agree?
Previously Swift enabled the "UseOdrIndicator" ASan instrumentation mode
and gave no option to disable this. This probably wasn't intentional but
happened due to the fact the
createModuleAddressSanitizerLegacyPassPass() function has a default
value for the UseOdrIndicator parameter of true and in Swift we
never specified this parameter explicitly.
Clang disables the "UseOdrIndicator" mode by default but allows it to be
enabled using the -fsanitize-address-use-odr-indicator flag.
Having "UseOdrIndicator" off by default is probably the right
default choice because it bloats the binary. So this patch changes the
Swift compiler to match Clang's behavior.
@danliew-apple: maybe we can also get one approval from the Swift team?
recover)); | ||
PM.add(createModuleAddressSanitizerLegacyPassPass( | ||
/*CompileKernel=*/false, recover, /*UseGlobalsGC=*/true, | ||
useODRIndicator)); |
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 note to myself: here is the place we are switching the default. We are now using an explicit value determined by the driver instead of the default specified in the header (which is true).
@brentdax Adding you as a reviewer because it looks like you recently changed stuff in the driver. |
@DougGregor Do the driver changes here cause any problems for the new swift swift driver? |
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.
As long as this change won't break any builds from before this new flag was introduced, it looks fine from the driver's perspective.
I believe analogous work will be necessary in the new driver. Rather than asking Doug to review, I'll just mention @artemcm and @nkcsgexi here so they know to schedule that.
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.
(Sorry, I was trying to remove Doug and it somehow got two others, too. GitHub for iOS bug, maybe?)
Yes, the Driver component of this PR will need to be implemented in https://github.com/apple/swift-driver also, to propagate the new flag to |
9856863
to
adfbd11
Compare
@yln Can you check you're okay with the new patch? |
@swift-ci Please smoke test |
@swift-ci Please test |
Build failed |
@@ -258,6 +258,22 @@ OptionSet<SanitizerKind> swift::parseSanitizerRecoverArgValues( | |||
return sanitizerRecoverSet; | |||
} | |||
|
|||
bool swift::parseSanitizerAddressUseODRIndicator( | |||
const llvm::opt::Arg *A, const OptionSet<SanitizerKind> &enabledSanitizers, |
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.
Given that we don't expect this to be NULL
(see below), I think that it would be better to change the signature to take the Arg
by reference (const llvm::opt::Arg &A
).
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 is a valid criticism but the use of llvm::opt::Arg*
here is deliberate. It's being used so that this new function follows a similar design as the other functions in include/swift/Option/SanitizerOptions.h
.
I'd prefer to keep the APIs as uniform as possible. Note I'm aware there are some oddities already in this file (inconsistent argument order) but we shouldn't add to them if we don't have to.
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 don't think its adding any inconsistency. The LLVM style actually encourages this - pass by reference unless you need to be able to pass in nullptr
as a reference to nullptr
is not well-formed.
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 wasn't talking about inconsistency with respect to LLVM's recommended style. I'm talking about inconsistency with respect to the APIs that already exist in SanitizerOptions.h
. They all take a llvm::opt::Arg*
. All of these could actually be Arg&
because they all assume that Arg* A
is not null. Deliberately adding an API that doesn't match the existing APIs is an unnecessary inconsistency. We could change all of the functions in the header but that's really out-of-scope for this PR. If you really want this that let's do that in a separate PR.
I suspect the reason these APIs take a llvm::opt::Arg*
right now is that is the type available at the use sites and so passing it directly was the most convenient thing to do.
@swift-ci test Linux |
Previously Swift enabled the "UseOdrIndicator" ASan instrumentation mode and gave no option to disable this. This probably wasn't intentional but happened due to the fact the `createModuleAddressSanitizerLegacyPassPass()` function has a default value for the `UseOdrIndicator` parameter of `true` and in Swift we never specified this parameter explicitly. Clang disables the "UseOdrIndicator" mode by default but allows it to be enabled using the `-fsanitize-address-use-odr-indicator` flag. Having "UseOdrIndicator" off by default is probably the right default choice because it bloats the binary. So this patch changes the Swift compiler to match Clang's behavior. This patch disables the "UseOdrIndicator" mode by default but adds a hidden driver and frontend flag (`-sanitize-address-use-odr-indicator`) to enable it. The flag is hidden so that we can remove it in the future if needed. A side effect of disabling "UseOdrIndicator" is that by we will no longer use private aliases for poisoning globals. Private aliases were introduced to avoid crashes (google/sanitizers#398) due to ODR violations with non-instrumented binaries. On Apple platforms the use of two-level namespaces probably means that using private aliases wasn't ever really necessary to avoid crashes. On platforms with a flat linking namespace (e.g. Linux) using private aliases might matter more but should users actually run into problems they can either: * Fix their environment to remove the ODR, thus avoiding the crash. * Instrument the previously non-instrumented code to avoid the crash. * Use the new `-sanitize-address-use-odr-indicator` flag rdar://problem/69335186
adfbd11
to
9208b52
Compare
@swift-ci Please smoke test |
@gottesmm Ping. |
@compnerd Thanks for approving. |
Previously Swift enabled the "UseOdrIndicator" ASan instrumentation mode
and gave no option to disable this. This probably wasn't intentional but
happened due to the fact the
createModuleAddressSanitizerLegacyPassPass()
function has a defaultvalue for the
UseOdrIndicator
parameter oftrue
and in Swift wenever specified this parameter explicitly.
Clang disables the "UseOdrIndicator" mode by default but allows it to be
enabled using the
-fsanitize-address-use-odr-indicator
flag.Having "UseOdrIndicator" off by default is probably the right
default choice because it bloats the binary. So this patch changes the
Swift compiler to match Clang's behavior.
This patch disables the "UseOdrIndicator" mode by default but adds a
hidden driver and frontend flag (
-sanitize-address-use-odr-indicator
)to enable it. The flag is hidden so that we can remove it in the future
if needed.
A side of disabling "UseOdrIndicator" is that by we will no longer use
private aliases for poisoning globals. Private aliases were introduced
to avoid crashes (google/sanitizers#398) due
to ODR violations with non-instrumented binaries. On Apple platforms the
use of two-level namespaces probably means that using private aliases
wasn't ever really necessary to avoid crashes. On platforms with a flat
linking namespace (e.g. Linux) using private aliases might matter more
but should users actually run into problems they can either:
-sanitize-address-use-odr-indicator
flagrdar://problem/69335186