Skip to content

http1 codec: fix possible call after release issue when server connection is destroyed#20629

Merged
KBaichoo merged 5 commits intoenvoyproxy:mainfrom
yanjunxiang-google:oss-patch
Apr 25, 2022
Merged

http1 codec: fix possible call after release issue when server connection is destroyed#20629
KBaichoo merged 5 commits intoenvoyproxy:mainfrom
yanjunxiang-google:oss-patch

Conversation

@yanjunxiang-google
Copy link
Copy Markdown
Contributor

@yanjunxiang-google yanjunxiang-google commented Apr 1, 2022

Fix lifetime issues in Envoy

Signed-off-by: Yanjun Xiang yanjunxiang@google.com

Commit Message:
Additional Description:
Risk Level:
Testing:
Docs Changes:
Release Notes:
Platform Specific Features:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Fixes commit #PR or SHA]
[Optional Deprecated:]
[Optional API Considerations:]

Signed-off-by: Yanjun Xiang <yanjunxiang@google.com>
@yanjunxiang-google
Copy link
Copy Markdown
Contributor Author

/assign @yanavlasov @adisuissa

@yanjunxiang-google
Copy link
Copy Markdown
Contributor Author

/retest

@repokitteh-read-only
Copy link
Copy Markdown

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #20629 (comment) was created by @yanjunxiang-google.

see: more, trace.

vitalybuka
vitalybuka previously approved these changes Apr 2, 2022
Copy link
Copy Markdown
Contributor

@vitalybuka vitalybuka left a comment

Choose a reason for hiding this comment

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

LGTM

@wbpcode
Copy link
Copy Markdown
Member

wbpcode commented Apr 2, 2022

Can you provide some more detailed context about this PR? When are there lifetime issues?
This PR update some code of HTTP codec and some code of access log manager. If it's necessary, may we should split this PR to different two PRs?

@wbpcode
Copy link
Copy Markdown
Member

wbpcode commented Apr 2, 2022

/wait-any
/assign

@vitalybuka
Copy link
Copy Markdown
Contributor

vitalybuka commented Apr 14, 2022

Msan with https://clang.llvm.org/docs/MemorySanitizer.html#use-after-destruction-detection reports the following on multiple tests

Here is for envoy/test/integration/integration_test.cc:

MemorySanitizer: use-of-uninitialized-value source/common/http/http1/codec_impl.cc:1238:3
    #0 In Envoy::Http::Http1::ServerConnectionImpl::releaseOutboundResponse(Envoy::Buffer::OwnedBufferFragmentImpl const*) common/http/http1/codec_impl.cc:1238:3
    #1 In operator() common/http/http1/codec_impl.cc:965:9
    #2 In __invoke<(lambda at common/http/http1/codec_impl.cc:964:33) &, const Envoy::Buffer::OwnedBufferFragmentImpl *> include/c++/v1/type_traits:3582:23
    #3 In __call<(lambda at common/http/http1/codec_impl.cc:964:33) &, const Envoy::Buffer::OwnedBufferFragmentImpl *> include/c++/v1/__functional/invoke.h:61:9
    #4 In operator() include/c++/v1/__functional/function.h:232:12
    #5 In void std::__msan::__function::__policy_invoker<void (Envoy::Buffer::OwnedBufferFragmentImpl const*)>::__call_impl<std::__msan::__function::__default_alloc_func<Envoy::Http::Http1::ServerConnectionImpl::ServerConnectionImpl(Envoy::Network::Connection&, Envoy::Http::Http1::CodecStats&, Envoy::Http::ServerConnectionCallbacks&, Envoy::Http::Http1Settings const&, unsigned int, unsigned int, envoy::config::core::v3::HttpProtocolOptions_HeadersWithUnderscoresAction)::$_8, void (Envoy::Buffer::OwnedBufferFragmentImpl const*)> >(std::__msan::__function::__policy_storage const*, Envoy::Buffer::OwnedBufferFragmentImpl const*) include/c++/v1/__functional/function.h:713:16
    #6 In operator() include/c++/v1/__functional/function.h:845:16
    #7 In operator() include/c++/v1/__functional/function.h:1186:12
    #8 In Envoy::Buffer::OwnedBufferFragmentImpl::done() common/buffer/buffer_impl.h:845:26
    #9 In operator() common/buffer/buffer_impl.h:93:46
    #10 In __invoke<(lambda at ./common/buffer/buffer_impl.h:93:21) &> include/c++/v1/type_traits:3582:23
    #11 In __call<(lambda at ./common/buffer/buffer_impl.h:93:21) &> include/c++/v1/__functional/invoke.h:61:9
    #12 In operator() include/c++/v1/__functional/function.h:232:12
    #13 In void std::__msan::__function::__policy_invoker<void ()>::__call_impl<std::__msan::__function::__default_alloc_func<Envoy::Buffer::Slice::Slice(Envoy::Buffer::BufferFragment&)::'lambda'(), void ()> >(std::__msan::__function::__policy_storage const*) include/c++/v1/__functional/function.h:713:16
    #14 In operator() include/c++/v1/__functional/function.h:845:16
    #15 In operator() include/c++/v1/__functional/function.h:1186:12
    #16 In Envoy::Buffer::Slice::callAndClearDrainTrackersAndCharges() common/buffer/buffer_impl.h:325:7
    #17 In Envoy::Buffer::Slice::~Slice() common/buffer/buffer_impl.h:132:14
    #18 In ~SliceDeque common/buffer/buffer_impl.h:427:7
    #19 In Envoy::Buffer::OwnedImpl::~OwnedImpl() common/buffer/buffer_impl.h:644:7
    #20 In Envoy::Buffer::WatermarkBuffer::~WatermarkBuffer() common/buffer/watermark_buffer.h:22:7
    #21 In Envoy::Buffer::WatermarkBuffer::~WatermarkBuffer() common/buffer/watermark_buffer.h:22:7
    #22 In operator() include/c++/v1/__memory/unique_ptr.h:57:5
    #23 In ~unique_ptr include/c++/v1/__memory/unique_ptr.h:275:7
    #24 In Envoy::Http::Http1::ConnectionImpl::~ConnectionImpl() common/http/http1/codec_impl.h:191:7
    #25 In Envoy::Http::Http1::ServerConnectionImpl::~ServerConnectionImpl() common/http/http1/codec_impl.h:431:7
    #26 In ~ServerConnectionImpl common/http/http1/codec_impl.h:431:7
    #27 In Envoy::Http::Http1::ServerConnectionImpl::~ServerConnectionImpl() common/http/http1/codec_impl.h:431:7
    #28 In operator() include/c++/v1/__memory/unique_ptr.h:57:5
    #29 In ~unique_ptr include/c++/v1/__memory/unique_ptr.h:275:7
    #30 In Envoy::Http::ConnectionManagerImpl::~ConnectionManagerImpl() common/http/conn_manager_impl.cc:182:1
    #31 In Envoy::Http::ConnectionManagerImpl::~ConnectionManagerImpl() common/http/conn_manager_impl.cc:162:49
    #32 In std::__msan::__shared_ptr_emplace<Envoy::Http::ConnectionManagerImpl, std::__msan::allocator<Envoy::Http::ConnectionManagerImpl> >::__on_zero_shared() include/c++/v1/__memory/shared_ptr.h:312:24
    #33 In __release_shared include/c++/v1/__memory/shared_ptr.h:174:9
    #34 In __release_shared include/c++/v1/__memory/shared_ptr.h:216:27
    #35 In ~shared_ptr include/c++/v1/__memory/shared_ptr.h:703:23
    #36 In ~ActiveReadFilter common/network/filter_manager_impl.h:116:10
    #37 In ~ActiveReadFilter common/network/filter_manager_impl.h:116:10
    #38 In Envoy::Network::FilterManagerImpl::ActiveReadFilter::~ActiveReadFilter() common/network/filter_manager_impl.h:116:10
    #39 In operator() include/c++/v1/__memory/unique_ptr.h:57:5
    #40 In ~unique_ptr include/c++/v1/__memory/unique_ptr.h:275:7
    #41 In destroy<std::__msan::unique_ptr<Envoy::Network::FilterManagerImpl::ActiveReadFilter, std::__msan::default_delete<Envoy::Network::FilterManagerImpl::ActiveReadFilter> >, void, void> include/c++/v1/__memory/allocator_traits.h:319:15
    #42 In std::__msan::__list_imp<std::__msan::unique_ptr<Envoy::Network::FilterManagerImpl::ActiveReadFilter, std::__msan::default_delete<Envoy::Network::FilterManagerImpl::ActiveReadFilter> >, std::__msan::allocator<std::__msan::unique_ptr<Envoy::Network::FilterManagerImpl::ActiveReadFilter, std::__msan::default_delete<Envoy::Network::FilterManagerImpl::ActiveReadFilter> > > >::clear() include/c++/v1/list:749:13
    #43 In ~__list_imp include/c++/v1/list:728:3
    #44 In ~FilterManagerImpl common/network/filter_manager_impl.h:102:7
    #45 In Envoy::Network::ConnectionImpl::~ConnectionImpl() common/network/connection_impl.cc:114:1
    #46 In Envoy::Network::ServerConnectionImpl::~ServerConnectionImpl() common/network/connection_impl.h:232:7
    #47 In ~ServerConnectionImpl common/network/connection_impl.h:232:7
    #48 In ~ServerConnectionImpl common/network/connection_impl.h:232:7
    #49 In virtual thunk to Envoy::Network::ServerConnectionImpl::~ServerConnectionImpl() common/network/connection_impl.h
    #50 In operator() include/c++/v1/__memory/unique_ptr.h:57:5
    #51 In ~unique_ptr include/c++/v1/__memory/unique_ptr.h:275:7
    #52 In Envoy::Server::ActiveTcpConnection::~ActiveTcpConnection() server/active_stream_listener_base.cc:108:1
    #53 In Envoy::Server::ActiveTcpConnection::~ActiveTcpConnection() server/active_stream_listener_base.cc:95:45

Important frames:

  #0 In Envoy::Http::Http1::ServerConnectionImpl::releaseOutboundResponse
  #24 In Envoy::Http::Http1::ConnectionImpl::~ConnectionImpl() common/http/http1/codec_impl.h:191:7
  #25 In Envoy::Http::Http1::ServerConnectionImpl::~ServerConnectionImpl() common/http/http1/codec_impl.h:431:7

ServerConnectionImpl is subclass of ConnectionImpl
So when we get into frame 24, all fields of ServerConnectionImpl are already destroyed.
However we touch one through callback and ServerConnectionImpl::releaseOutboundResponse.

Accessing field after lifetime, even trivial, is undefined behaviour is c++.

Copy link
Copy Markdown
Member

@wbpcode wbpcode left a comment

Choose a reason for hiding this comment

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

Hi, thanks for your kind reply. This work is great and valueable. 🌷

Could you create a seperated PR for the HTTP1 code updates? Then we can merge it first.
And could you provide some more context about the lifetime issue of access log manager? Thanks. 😄

Comment thread source/common/http/http1/codec_impl.cc Outdated
Comment on lines +304 to +308
// It's messy and complicated to try to tag the final write of an HTTP response for response
// tracking for flood protection. Instead, write an empty buffer fragment after the response,
// to allow for tracking.
// When the response is written out, the fragment will be deleted and the counter will be updated
// by ServerConnectionImpl::releaseOutboundResponse()
// It's messy and complicated to try to tag the final write of an HTTP
// response for response tracking for flood protection. Instead, write an
// empty buffer fragment after the response, to allow for tracking. When the
// response is written out, the fragment will be deleted and the counter will
// be updated by response_buffer_releasor_.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks these comment changes are uncessary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The patch removes ServerConnectionImpl::releaseOutboundResponse mentioned in the comment

Copy link
Copy Markdown
Member

@wbpcode wbpcode Apr 16, 2022

Choose a reason for hiding this comment

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

Get it. But looks like there is some re-formatting. Ingore my comment, this is just a nit problem.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you create a seperated PR for the HTTP1 code updates? Then we can merge it first. And could you provide some more context about the lifetime issue of access log manager? Thanks. smile

This explains source/common/access_log/access_log_manager_impl.* changes
and propose a different fix for crash in envoy/test/extensions/filters/http/grpc_json_transcoder/grpc_json_transcoder_integration_test.cc

==7987==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 in Envoy::AccessLog::AccessLogFileImpl::doWrite(Envoy::Buffer::Instance&) source/common/access_log/access_log_manager_impl.cc
    #1 in Envoy::AccessLog::AccessLogFileImpl::~AccessLogFileImpl() source/common/access_log/access_log_manager_impl.cc:91:7
    #2 in std::__msan::__shared_ptr_emplace<Envoy::AccessLog::AccessLogFileImpl, std::__msan::allocator<Envoy::AccessLog::AccessLogFileImpl> >::__on_zero_shared() include/c++/v1/__memory/shared_ptr.h:315:24
    #3 in __release_shared include/c++/v1/__memory/shared_ptr.h:177:9
    #4 in __release_shared include/c++/v1/__memory/shared_ptr.h:219:27
    #5 in ~shared_ptr include/c++/v1/__memory/shared_ptr.h:706:23
    #6 in Envoy::Extensions::AccessLoggers::File::FileAccessLog::~FileAccessLog() source/extensions/access_loggers/common/file_access_log_impl.h:14:7
    #7 in std::__msan::__shared_ptr_emplace<Envoy::Extensions::AccessLoggers::File::FileAccessLog, std::__msan::allocator<Envoy::Extensions::AccessLoggers::File::FileAccessLog> >::__on_zero_shared() include/c++/v1/__memory/shared_ptr.h:315:24
    #8 in __release_shared include/c++/v1/__memory/shared_ptr.h:177:9
    #9 in __release_shared include/c++/v1/__memory/shared_ptr.h:219:27
    #10 in ~shared_ptr include/c++/v1/__memory/shared_ptr.h:706:23
    #11 in destroy<std::__msan::shared_ptr<Envoy::AccessLog::Instance>, void, void> include/c++/v1/__memory/allocator_traits.h:319:15
    #12 in clear include/c++/v1/list:749:13
    #13 in std::__msan::__list_imp<std::__msan::shared_ptr<Envoy::AccessLog::Instance>, std::__msan::allocator<std::__msan::shared_ptr<Envoy::AccessLog::Instance> > >::~__list_imp() include/c++/v1/list:728:3
    #14 in Envoy::Server::AdminImpl::~AdminImpl() source/server/admin/admin.h:64:7
    #15 in Envoy::Server::AdminImpl::~AdminImpl() source/server/admin/admin.h:64:7
    #16 in operator() include/c++/v1/__memory/unique_ptr.h:57:5
    #17 in ~unique_ptr include/c++/v1/__memory/unique_ptr.h:275:7
    #18 in Envoy::Server::InstanceImpl::~InstanceImpl() source/server/server.cc:163:1
    #19 in Envoy::IntegrationTestServerImpl::createAndRunEnvoyServer(Envoy::OptionsImpl&, Envoy::Event::TimeSystem&, std::__msan::shared_ptr<Envoy::Network::Address::Instance const>, Envoy::ListenerHooks&, Envoy::Thread::BasicLockable&, Envoy::Server::ComponentFactory&, std::__msan::unique_ptr<Envoy::Random::RandomGenerator, std::__msan::default_delete<Envoy::Random::RandomGenerator> >&&, std::__msan::optional<std::__msan::reference_wrapper<Envoy::ProcessObject> >, std::__msan::shared_ptr<Envoy::Buffer::WatermarkFactory>) test/integration/server.cc:243:3
    #20 in Envoy::IntegrationTestServer::threadRoutine(Envoy::Network::Address::IpVersion, std::__msan::optional<unsigned long>, std::__msan::optional<std::__msan::reference_wrapper<Envoy::ProcessObject> >, Envoy::Server::FieldValidationConfig, unsigned int, std::__msan::chrono::duration<long long, std::__msan::ratio<1l, 1l> >, Envoy::Server::DrainStrategy, std::__msan::shared_ptr<Envoy::Buffer::WatermarkFactory>) test/integration/server.cc:201:3
    #21 in operator() test/integration/server.cc:108:5
    #22 in __invoke<(lambda at test/integration/server.cc:105:47) &> include/c++/v1/type_traits:3493:23
    #23 in __call<(lambda at test/integration/server.cc:105:47) &> include/c++/v1/__functional/invoke.h:61:9
    #24 in operator() include/c++/v1/__functional/function.h:232:12
    #25 in void std::__msan::__function::__policy_invoker<void ()>::__call_impl<std::__msan::__function::__default_alloc_func<Envoy::IntegrationTestServer::start(Envoy::Network::Address::IpVersion, std::__msan::function<void ()>, std::__msan::optional<unsigned long>, bool, std::__msan::optional<std::__msan::reference_wrapper<Envoy::ProcessObject> >, Envoy::Server::FieldValidationConfig, unsigned int, std::__msan::chrono::duration<long long, std::__msan::ratio<1l, 1l> >, Envoy::Server::DrainStrategy, std::__msan::shared_ptr<Envoy::Buffer::WatermarkFactory>)::$_2, void ()> >(std::__msan::__function::__policy_storage const*) include/c++/v1/__functional/function.h:713:16
    #26 in operator() include/c++/v1/__functional/function.h:845:16
    #27 in operator() include/c++/v1/__functional/function.h:1186:12
    #28 in operator() source/common/common/posix/thread_impl.cc:49:11
    #29 in Envoy::Thread::ThreadImplPosix::ThreadImplPosix(std::__msan::function<void ()>, std::__msan::optional<Envoy::Thread::Options> const&)::'lambda'(void*)::__invoke(void*) source/common/common/posix/thread_impl.cc:48:9
    #30 in start_thread (/usr/grte/v5/lib64/libpthread.so.0)
    #31 in clone (/usr/grte/v5/lib64/libc.so.6)

  Memory was marked as uninitialized
    #0 in __sanitizer_dtor_callback llvm-project/compiler-rt/lib/msan/msan_interceptors.cpp:940:5
    #1 in Envoy::AccessLog::AccessLogManagerImpl::~AccessLogManagerImpl() source/common/access_log/access_log_manager_impl.cc:22:1
    #2 in Envoy::Server::InstanceImpl::~InstanceImpl() source/server/server.cc:163:1
    #3 in Envoy::IntegrationTestServerImpl::createAndRunEnvoyServer(Envoy::OptionsImpl&, Envoy::Event::TimeSystem&, std::__msan::shared_ptr<Envoy::Network::Address::Instance const>, Envoy::ListenerHooks&, Envoy::Thread::BasicLockable&, Envoy::Server::ComponentFactory&, std::__msan::unique_ptr<Envoy::Random::RandomGenerator, std::__msan::default_delete<Envoy::Random::RandomGenerator> >&&, std::__msan::optional<std::__msan::reference_wrapper<Envoy::ProcessObject> >, std::__msan::shared_ptr<Envoy::Buffer::WatermarkFactory>) test/integration/server.cc:243:3
    #4 in Envoy::IntegrationTestServer::threadRoutine(Envoy::Network::Address::IpVersion, std::__msan::optional<unsigned long>, std::__msan::optional<std::__msan::reference_wrapper<Envoy::ProcessObject> >, Envoy::Server::FieldValidationConfig, unsigned int, std::__msan::chrono::duration<long long, std::__msan::ratio<1l, 1l> >, Envoy::Server::DrainStrategy, std::__msan::shared_ptr<Envoy::Buffer::WatermarkFactory>) test/integration/server.cc:201:3
    #5 in operator() test/integration/server.cc:108:5
    #6 in __invoke<(lambda at test/integration/server.cc:105:47) &> include/c++/v1/type_traits:3493:23
    #7 in __call<(lambda at test/integration/server.cc:105:47) &> include/c++/v1/__functional/invoke.h:61:9
    #8 in operator() include/c++/v1/__functional/function.h:232:12
    #9 in void std::__msan::__function::__policy_invoker<void ()>::__call_impl<std::__msan::__function::__default_alloc_func<Envoy::IntegrationTestServer::start(Envoy::Network::Address::IpVersion, std::__msan::function<void ()>, std::__msan::optional<unsigned long>, bool, std::__msan::optional<std::__msan::reference_wrapper<Envoy::ProcessObject> >, Envoy::Server::FieldValidationConfig, unsigned int, std::__msan::chrono::duration<long long, std::__msan::ratio<1l, 1l> >, Envoy::Server::DrainStrategy, std::__msan::shared_ptr<Envoy::Buffer::WatermarkFactory>)::$_2, void ()> >(std::__msan::__function::__policy_storage const*) include/c++/v1/__functional/function.h:713:16
    #10 in operator() include/c++/v1/__functional/function.h:845:16
    #11 in operator() include/c++/v1/__functional/function.h:1186:12
    #12 in operator() source/common/common/posix/thread_impl.cc:49:11
    #13 in Envoy::Thread::ThreadImplPosix::ThreadImplPosix(std::__msan::function<void ()>, std::__msan::optional<Envoy::Thread::Options> const&)::'lambda'(void*)::__invoke(void*) source/common/common/posix/thread_impl.cc:48:9
    #14 in start_thread (/usr/grte/v5/lib64/libpthread.so.0)

Important frames only:

==7987==WARNING: MemorySanitizer: use-of-uninitialized-value
   // Destroyes admin_ which calls into https://github.com/envoyproxy/envoy/blob/052f94ef7e42347366b1af31b2b7035d3c98463b/source/common/access_log/access_log_manager_impl.cc#L116.
    #0 in Envoy::AccessLog::AccessLogFileImpl::doWrite(Envoy::Buffer::Instance&) source/common/access_log/access_log_manager_impl.cc
    #15 in Envoy::Server::AdminImpl::~AdminImpl() source/server/admin/admin.h:64:7
    #18 in Envoy::Server::InstanceImpl::~InstanceImpl() source/server/server.cc:163:1

  Memory was marked as uninitialized
    // Destroyes access_log_manager_.
    #1 in Envoy::AccessLog::AccessLogManagerImpl::~AccessLogManagerImpl() source/common/access_log/access_log_manager_impl.cc:22:1
    #2 in Envoy::Server::InstanceImpl::~InstanceImpl() source/server/server.cc:163:1

access_log_manager_ member is being destroyed before admin_.
The better fix is just to reorder members:

==== envoy/src/source/server/server.cc ====
--- envoy/src/source/server/server.cc
+++ envoy/src/source/server/server.cc
@@ -82,11 +82,11 @@
           process_context ? ProcessContextOptRef(std::ref(*process_context)) : absl::nullopt,
           watermark_factory)),
       dispatcher_(api_->allocateDispatcher("main_thread")),
+      access_log_manager_(options.fileFlushIntervalMsec(), *api_, *dispatcher_, access_log_lock,
+                          store),
       singleton_manager_(new Singleton::ManagerImpl(api_->threadFactory())),
       handler_(new ConnectionHandlerImpl(*dispatcher_, absl::nullopt)),
       listener_component_factory_(*this), worker_factory_(thread_local_, *api_, hooks),
-      access_log_manager_(options.fileFlushIntervalMsec(), *api_, *dispatcher_, access_log_lock,
-                          store),
       terminated_(false),
       mutex_tracer_(options.mutexTracingEnabled() ? &Envoy::MutexTracerImpl::getOrCreateTracer()
                                                   : nullptr),
==== envoy/src/source/server/server.h ====
--- envoy/src/source/server/server.h
+++ envoy/src/source/server/server.h
@@ -359,6 +359,7 @@
   envoy::config::bootstrap::v3::Bootstrap bootstrap_;
   Api::ApiPtr api_;
   Event::DispatcherPtr dispatcher_;
+  AccessLog::AccessLogManagerImpl access_log_manager_;
   std::unique_ptr<AdminImpl> admin_;
   Singleton::ManagerPtr singleton_manager_;
   Network::ConnectionHandlerPtr handler_;
@@ -374,7 +375,6 @@
   Network::DnsResolverSharedPtr dns_resolver_;
   Event::TimerPtr stat_flush_timer_;
   DrainManagerPtr drain_manager_;
-  AccessLog::AccessLogManagerImpl access_log_manager_;
   std::unique_ptr<Upstream::ClusterManagerFactory> cluster_manager_factory_;
   std::unique_ptr<Server::GuardDog> main_thread_guard_dog_;
   std::unique_ptr<Server::GuardDog> worker_guard_dog_;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @vitalybuka for the detail root cause analysis.

Based on the discussion, I splitted the access log part to a separate PR: #20913.
PTAL

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great, thanks for your detailed explaination. @vitalybuka 👍 🌷

@wbpcode
Copy link
Copy Markdown
Member

wbpcode commented Apr 18, 2022

/wait-any

Signed-off-by: Yanjun Xiang <yanjunxiang@google.com>
@yanjunxiang-google
Copy link
Copy Markdown
Contributor Author

/retest

@repokitteh-read-only
Copy link
Copy Markdown

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #20629 (comment) was created by @yanjunxiang-google.

see: more, trace.

@wbpcode wbpcode changed the title Fix lifetime issues in Envoy http1 codec: fix possible call after release issue when server connection is destroyed Apr 21, 2022
wbpcode
wbpcode previously approved these changes Apr 21, 2022
Copy link
Copy Markdown
Member

@wbpcode wbpcode left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks @yanjunxiang-google @vitalybuka

cc @KBaichoo for a second pass or merge.

@wbpcode wbpcode assigned KBaichoo and unassigned adisuissa and yanavlasov Apr 21, 2022
@KBaichoo
Copy link
Copy Markdown
Contributor

KBaichoo commented Apr 21, 2022

I think we could also fix this by moving up the outbound_responses_ up above the output buffer whose dtor triggers the drain callback on the fragments which touch the outbound memory that's freed in ~ServerConnectionImpl.

A better approach might be pushing down the output buffer ownership to the individual Server/Client ConnectionImpl and have the ConnectionImpl just have a pointer to it from the derived classes. For the ServerConnectionImpl the buffer should be destroyed before the release fragment.

Signed-off-by: Yanjun Xiang <yanjunxiang@google.com>
Signed-off-by: Yanjun Xiang <yanjunxiang@google.com>
Copy link
Copy Markdown
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

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

looks good otherwise!

[&]() -> void { this->onBelowLowWatermark(); },
[&]() -> void { this->onAboveHighWatermark(); },
[]() -> void { /* TODO(adisuissa): handle overflow watermark */ })) {
// Inform parent
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Signed-off-by: Yanjun Xiang <yanjunxiang@google.com>
@yanjunxiang-google
Copy link
Copy Markdown
Contributor Author

/retest

@repokitteh-read-only
Copy link
Copy Markdown

Retrying Azure Pipelines:
Retried failed jobs in: envoy-presubmit

🐱

Caused by: a #20629 (comment) was created by @yanjunxiang-google.

see: more, trace.

Copy link
Copy Markdown
Contributor

@KBaichoo KBaichoo left a comment

Choose a reason for hiding this comment

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

lgtm!

@KBaichoo KBaichoo merged commit c58d5ad into envoyproxy:main Apr 25, 2022
@yanjunxiang-google yanjunxiang-google deleted the oss-patch branch April 25, 2022 14:42
ravenblackx pushed a commit to ravenblackx/envoy that referenced this pull request Jun 8, 2022
…tion is destroyed (envoyproxy#20629)

* Fix lifetime issues in Envoy

Signed-off-by: Yanjun Xiang <yanjunxiang@google.com>
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.

6 participants