-
Notifications
You must be signed in to change notification settings - Fork 27
Fix sigabrt in module integration tests #421
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
Changes from all commits
d7d4856
f9a273c
ee5c4e8
c1f3d55
57a9221
4d2902b
2316a02
d7e41da
62617f3
2fd5c29
c43c973
b7e6ecd
0e13a9d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,19 +18,46 @@ | |
| namespace viam { | ||
| namespace sdk { | ||
|
|
||
| const std::shared_ptr<grpc::Channel>& ViamChannel::channel() const { | ||
| return channel_; | ||
| } | ||
| struct ViamChannel::impl { | ||
| impl(const char* path, void* runtime) : path(path), rust_runtime(runtime) {} | ||
|
|
||
| void ViamChannel::close() { | ||
| if (closed_) { | ||
| return; | ||
| impl(const impl&) = delete; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think because you are declaring the move ops that the copy ops are implicitly deleted, but if you don't trust that and want to make it explicit I don't mind either. |
||
|
|
||
| impl(impl&& other) noexcept | ||
| : path(std::exchange(other.path, nullptr)), | ||
| rust_runtime(std::exchange(other.rust_runtime, nullptr)) {} | ||
|
|
||
| impl& operator=(const impl&) = delete; | ||
|
|
||
| impl& operator=(impl&& other) noexcept { | ||
| path = std::exchange(other.path, nullptr); | ||
| rust_runtime = std::exchange(other.rust_runtime, nullptr); | ||
|
|
||
| return *this; | ||
| } | ||
| closed_ = true; | ||
| free_string(path_); | ||
| free_rust_runtime(rust_runtime_); | ||
|
|
||
| ~impl() { | ||
| free_string(path); | ||
| free_rust_runtime(rust_runtime); | ||
| } | ||
|
|
||
| const char* path; | ||
| void* rust_runtime; | ||
| }; | ||
|
|
||
| ViamChannel::ViamChannel(std::shared_ptr<grpc::Channel> channel, const char* path, void* runtime) | ||
| : channel_(std::move(channel)), pimpl_(std::make_unique<ViamChannel::impl>(path, runtime)) {} | ||
|
|
||
| ViamChannel::ViamChannel(std::shared_ptr<grpc::Channel> channel) : channel_(std::move(channel)) {} | ||
|
|
||
| ViamChannel::ViamChannel(ViamChannel&&) noexcept = default; | ||
|
|
||
| ViamChannel& ViamChannel::operator=(ViamChannel&&) noexcept = default; | ||
|
|
||
| ViamChannel::~ViamChannel() { | ||
| close(); | ||
| } | ||
|
|
||
| const std::string& Credentials::type() const { | ||
| return type_; | ||
| } | ||
|
|
@@ -39,9 +66,6 @@ const std::string& Credentials::payload() const { | |
| return payload_; | ||
| } | ||
|
|
||
| ViamChannel::ViamChannel(std::shared_ptr<grpc::Channel> channel, const char* path, void* runtime) | ||
| : channel_(std::move(channel)), path_(path), closed_(false), rust_runtime_(runtime) {} | ||
|
|
||
| DialOptions::DialOptions() = default; | ||
|
|
||
| DialOptions& DialOptions::set_credentials(boost::optional<Credentials> creds) { | ||
|
|
@@ -105,8 +129,8 @@ bool DialOptions::allows_insecure_downgrade() const { | |
| return allow_insecure_downgrade_; | ||
| } | ||
|
|
||
| std::shared_ptr<ViamChannel> ViamChannel::dial_initial( | ||
| const char* uri, const boost::optional<DialOptions>& options) { | ||
| ViamChannel ViamChannel::dial_initial(const char* uri, | ||
| const boost::optional<DialOptions>& options) { | ||
| DialOptions opts = options.get_value_or(DialOptions()); | ||
| auto timeout = opts.timeout(); | ||
| auto attempts_remaining = opts.initial_connection_attempts(); | ||
|
|
@@ -129,11 +153,10 @@ std::shared_ptr<ViamChannel> ViamChannel::dial_initial( | |
| } | ||
| // the while loop will run until we either return or throw an error, so we can never reach this | ||
| // point | ||
| BOOST_UNREACHABLE_RETURN(nullptr) | ||
| BOOST_UNREACHABLE_RETURN(ViamChannel(nullptr)) | ||
| } | ||
|
|
||
| std::shared_ptr<ViamChannel> ViamChannel::dial(const char* uri, | ||
| const boost::optional<DialOptions>& options) { | ||
| ViamChannel ViamChannel::dial(const char* uri, const boost::optional<DialOptions>& options) { | ||
| void* ptr = init_rust_runtime(); | ||
| const DialOptions opts = options.get_value_or(DialOptions()); | ||
| const std::chrono::duration<float> float_timeout = opts.timeout(); | ||
|
|
@@ -157,12 +180,19 @@ std::shared_ptr<ViamChannel> ViamChannel::dial(const char* uri, | |
|
|
||
| std::string address("unix://"); | ||
| address += socket_path; | ||
| const std::shared_ptr<grpc::Channel> channel = | ||
| impl::create_viam_channel(address, grpc::InsecureChannelCredentials()); | ||
| const std::unique_ptr<viam::robot::v1::RobotService::Stub> st = | ||
| viam::robot::v1::RobotService::NewStub(channel); | ||
| return std::make_shared<ViamChannel>(channel, socket_path, ptr); | ||
| }; | ||
|
|
||
| return ViamChannel(sdk::impl::create_viam_channel(address, grpc::InsecureChannelCredentials()), | ||
| socket_path, | ||
| ptr); | ||
| } | ||
|
|
||
| const std::shared_ptr<grpc::Channel>& ViamChannel::channel() const { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was this just unimplemented before? If so, maybe that means nobody was using it, and therefore it could be renamed to something like
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry weird
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So yes this was used, but I have taken this opportunity to remove the data member |
||
| return channel_; | ||
| } | ||
|
|
||
| void ViamChannel::close() { | ||
| pimpl_.reset(); | ||
| } | ||
|
|
||
| unsigned int Options::refresh_interval() const { | ||
| return refresh_interval_; | ||
|
|
||
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.
Woah. This was also a double destroy for all these
std::threadobjects, right? I'm sort of amazed this went unnoticed for so long. Are we doing ASAN / UBSAN builds anywhere in CI? If not, I think it might be time to do so.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.
our unit tests in CI run with santized builds for shared libraries, but our sanitizer seems to only be ubsan, not asan. i'm pretty surprised this hasn't been caught before either, and same with the other main issue being resolved in this PR which is that we had an instance of rust-utils
free_stringbeing called on ac_strmanaged by astd::string. perhaps a blessing in disguise that logging directed us to these!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.
ASAN and UBSAN work together just fine so it might be pretty easy to light it up.
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.
iirc turning on ASAN causes compilation to fail because it modifies the underlying memory shape but gRPC is not being compiled with ASAN, leading to ABI errors (I might have the details here somewhat wrong). Definitely fixable but it means compiling gRPC by hand in tests, which I believe is why we haven't done it thus far.
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.
Yes, that's right. That's a nuisance, and one I'd forgotten about since most of my time with ASAN was in a world where all third party C++ dependencies were vendored (in large part, exactly to solve this). I wonder if
conancan be leveraged to solve this for us since it will build dependencies from source.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.
Realizing I encountered this too yesterday when trying to debug the original issue in this PR. As for conan, here is a discussion from 1.x but the answer is 'kinda sorta' conan-io/conan#4754