-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
exception: make Ipv6Instance and Ipv4Instance not throw and remove some try catch pattern #16122
exception: make Ipv6Instance and Ipv4Instance not throw and remove some try catch pattern #16122
Conversation
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.
looks great, thank! Mostly just don't want to drop error message detail here.
We need a template method to return different type of instance instead of a ptr to their base class because some Instance has non-virtual method. I would like to name these two methods createInstancePtr and createInstance. |
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 what state this is in. Can you ping me directly when this is ready for another round of deep review?
Per f2f discussion, in cases where there are a large number of references to raw constructors in the codebase, a better way to go might be:
This way most of the call-sites don't need to change, but we are verifying you can only call them in the main thread context. I think the tricky part is the pattern of having the throwing constructor calling the non-throwing one as it won't have a good place to store the Status. So factoring out the logic might be a little annoying. One possible remedy is to put all the logic in an 'init' method that returns the Status, so the two calls are:
The drawback here is that you won't be able to use contructor-initializers which means none of the member vars can be const. Not sure how important that is. |
I think it is fine to change all the caller, since most of the code that call instance constructor directly are inside a test file instead of source code, it is safe to replace them all. |
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 think you are basically on the right track but need a few passes to clean up, factor out common patterns like "OrDie" correctly, avoid swallowing errors where they weren't swallowed before.
source/common/network/utility.cc
Outdated
} | ||
NOT_REACHED_GCOVR_EXCL_LINE; | ||
if (!addr.ok()) { | ||
return nullptr; |
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.
previously an error here would have resulted in a Throw, right? Should we return the StatusOr here so that callers can find the error message where they previously had caught an error and logged it in context?
In general you should make sure your changes don't drop information that may be needed when debugging a crash with logs.
source/extensions/filters/listener/proxy_protocol/proxy_protocol.cc
Outdated
Show resolved
Hide resolved
source/extensions/filters/network/redis_proxy/conn_pool_impl.cc
Outdated
Show resolved
Hide resolved
25ae987
to
6f8c113
Compare
Change the implementation of addressFromSockAddr(), parseInternetAddressNoThrow() and getAddressWithPort() |
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
/wait |
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
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.
Thanks so much, Chaoqin! This looks like a great improvement and a major step in the right direction.
/assign-from @envoyproxy/senior-maintainers
@envoyproxy/senior-maintainers assignee is @htuch |
@@ -53,6 +69,21 @@ class InstanceBase : public Instance { | |||
const Type type_; | |||
}; | |||
|
|||
class InstanceFactory { |
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.
Since this is used in multiple .cc
, it's basically a public interface, can you please document it better? Thanks.
source/common/network/address_impl.h
Outdated
absl::Status status; | ||
// Use new instead of make_unique here because the instance constructors are private and must be | ||
// called directly here. | ||
std::unique_ptr<InstanceType> instance(new InstanceType(status, std::forward<Args>(args)...)); |
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 are we no longer returning shared ptr but instead unique ptr?
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 I think I never fully understood the answer to 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.
Returning a unique_ptr from factory is a good practice because it makes the interface more general. unique_ptr can be implicitly cast to shared_ptr but not vice versa. So return a unique_ptr is equivalent to return a unique_ptr or shared_ptr.
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 think it's probably better not to change this interface in this PR just because it's better practice. A separate PR can be filed for that.
Large PRs that change semantics should minimize other changes, especially to interfaces.
@@ -77,6 +77,15 @@ StatusOr<Address::InstanceConstSharedPtr> addressFromSockAddr(const sockaddr_sto | |||
NOT_REACHED_GCOVR_EXCL_LINE; | |||
} | |||
|
|||
Address::InstanceConstSharedPtr addressFromSockAddrOrThrow(const sockaddr_storage& ss, | |||
socklen_t ss_len, bool v6only) { | |||
StatusOr<InstanceConstSharedPtr> address = addressFromSockAddr(ss, ss_len, v6only); |
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.
Maybe I'm missing something here, but it seems we're not improving anything if we're still either throwing or dying on the working thread?
Can you maybe explain the context of this PR so I can understand scope better. I.e. what's the long term game plan here.
/wait |
This was an attempt to remove 2 TRY_NEEDS_AUDIT at first. But the try in the dns_impl.cc can't be actually removed because of fuzz test issue, so we only remove the TRY_NEEDS_AUDIT in addressFromSockAddrOrDie. I think eventually we want to clean up all the TRY_NEEDS_AUDIT by either whitelisting them or refactoring them. |
the non-throw constructor of address instance allow creating an instance in worker thread without throwing, though I can't find any code where these error status can be handled and then return back to normal execution. |
From my point of view, we are trying to clean up the TRY_NEEDS_AUDIT. |
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
memset(&ip_.ipv4_.address_, 0, sizeof(ip_.ipv4_.address_)); | ||
ip_.ipv4_.address_.sin_family = AF_INET; | ||
ip_.ipv4_.address_.sin_port = htons(port); | ||
ip_.ipv4_.address_.sin_addr.s_addr = INADDR_ANY; | ||
friendly_name_ = absl::StrCat("0.0.0.0:", port); | ||
validateIpv4Supported(friendly_name_); |
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 can't initHelper()
or some variant be used here?
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.
Friendly ping
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.
because initHelper() is used to remove duplicate code in throw and not throw version of ctors, we don't have a not throw version of this ctor.
Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
@@ -300,8 +357,40 @@ PipeInstance::PipeInstance(const std::string& pipe_path, mode_t mode, | |||
pipe_.mode_ = mode; | |||
} | |||
|
|||
PipeInstance::PipeInstance(absl::Status& error, const sockaddr_un* address, socklen_t ss_len, |
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 spotting where this new constructor variant is used, can you point out?
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.
Address::InstanceFactory::createInstancePtrAddress::PipeInstance(sun, ss_len); In addressFromSockAddr()
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 as a step forward, I guess we're not fundamentally changing exception safety yet here.
// Use a raw try here because it is used in both main thread and filter. | ||
// Can not convert to use status code as there may be unexpected exceptions in server fuzz | ||
// tests, which must be handled. Potential exception may come from getAddressWithPort() or | ||
// portFromTcpUrl(). |
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.
Nit: seems unrelated, but since it's a minor comment fix don't feel that strongly.
…bridge-stream * upstream/main: (268 commits) tools: adding dio,better comments (envoyproxy#17104) doc: fix misplaced #[extension-category] for Wasm runtimes (envoyproxy#17078) ci: Speedup deps precheck (envoyproxy#17102) doc: fix wrong link on wasm network filter. (envoyproxy#17079) docs: Added v3 API reference. (envoyproxy#17095) docs: Update include paths in repo (envoyproxy#17098) exception: make Ipv6Instance and Ipv4Instance not throw and remove some try catch pattern (envoyproxy#16122) tools: adding reminders for API shephards (envoyproxy#17081) ci: Fix wasm verify example (envoyproxy#17086) [fuzz]: fix oss fuzz bug 34515, limit maglev table size (envoyproxy#16671) test: silencing flaky test (envoyproxy#17084) Set `validate` flag when the SAN(SubjectAltName) matching is performed (envoyproxy#16816) Listener: reset the file event when destroying listener filters (envoyproxy#16952) docs: link additional filters that emit dynamic metadata (envoyproxy#17059) rds: add config reload time stat for rds (envoyproxy#17033) bazel: Use color by default for build and run commands (envoyproxy#17077) ci: Add timing for docker pull (envoyproxy#17074) [Windows] Adding note section in Original Source HTTP Filter (envoyproxy#17058) quic: add quic version counters in http3 codec stats. (envoyproxy#16943) quiche: change crypto stream factory interfaces (envoyproxy#17046) ... Signed-off-by: Garrett Bourg <bourg@squareup.com>
…me try catch pattern (envoyproxy#16122) Commit Message:This is part of the effort to remove C++ exception from data plane by adding assertion that the code is executed in main thread when an exception is caught.(envoyproxy#14320) By making the constructor of instances(PipeInstance, Ipv6Instance, Ipv4Instance) no throw, remove some try catch code from envoy. Signed-off-by: chaoqin-li1123 <chaoqinli@google.com> Signed-off-by: chris.xin <xinchuantao@qq.com>
#16122 added asserts to utilities to make sure they were called from the correct thread. Over on the Envoy mobile side when we do QUIC we're doing it from the main thread, and failing some of the assert checks. I think the right thing to do here is just remove the assert This is the only use of isWorkerThread() so I'm inclined to just remove it. cc @goaway Risk Level: n/a Testing: n/a Docs Changes: n/a Release Notes: n/a Signed-off-by: Alyssa Wilk <alyssar@chromium.org>
…me try catch pattern (envoyproxy#16122) Commit Message:This is part of the effort to remove C++ exception from data plane by adding assertion that the code is executed in main thread when an exception is caught.(envoyproxy#14320) By making the constructor of instances(PipeInstance, Ipv6Instance, Ipv4Instance) no throw, remove some try catch code from envoy. Signed-off-by: chaoqin-li1123 <chaoqinli@google.com>
For an explanation of how to fill out the fields, please see the relevant section
in PULL_REQUESTS.md
Commit Message:This is part of the effort to remove C++ exception from data plane by adding assertion that the code is executed in main thread when an exception is caught.(#14320) By making the constructor of instances(PipeInstance, Ipv6Instance, Ipv4Instance) no throw, remove some try catch code from envoy.
Additional Description:
Risk Level:
Testing:
Docs Changes:
Release Notes:
Platform Specific Features:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Deprecated:]
[Optional API Considerations:]