facebook / proxygen

A collection of C++ HTTP libraries including an easy to use HTTP server.
Other
8.16k stars 1.5k forks source link

Error while replacing HTTPConnector #463

Closed SteveSelva closed 1 year ago

SteveSelva commented 1 year ago

I am trying to implement my own HTTPConnector for creating connections in Upstream. But when I use my connector in place of proxygen::HTTPConnector in ProxyService::ProxyHandler, it throws me MemoryAccessViolation exception. I even tried copying the HTTPConnector.h file and HTTPConnector.cpp file as it is and just changed the name of the class and file. Still that didn't work. And also I can't include that file in my project, it throws the exception. I have to exclude those files from my project and add back proxygen::HTTPConnector for it to work normally.

HTTPServerAcceptor.cpp

HTTPTransactionHandler* HTTPServerAcceptor::newHandler(
    HTTPTransaction& txn, HTTPMessage* msg) noexcept {

  SocketAddress clientAddr, vipAddr;
  txn.getPeerAddress(clientAddr);       //Error occurs at this line HTTPServerAcceptor.cpp@Line-104
  txn.getLocalAddress(vipAddr);
  msg->setClientAddress(clientAddr);
  msg->setDstAddress(vipAddr);

  // Create filters chain
  RequestHandler* h = nullptr;
  for (auto& factory : handlerFactories_) {
    h = factory->onRequest(h, msg);
  }

  return new RequestHandlerAdaptor(h);
}

When I check the function, txn.getPeerAddress(), the Peer Address was NULL causing MemoryAccessViolation. But I don't know how changing the HTTPConnector affects here.

Call Stacktrace

    vcruntime140d.dll!memcpy() Line 538 Unknown No symbols loaded.
>   ProxyServer.exe!folly::SocketAddress::operator=(const folly::SocketAddress & addr) Line 115 C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTPServerAcceptor::newHandler(proxygen::HTTPTransaction & txn, proxygen::HTTPMessage * msg) Line 104 C++ Symbols loaded.
    ProxyServer.exe!proxygen::SimpleController::getRequestHandler(proxygen::HTTPTransaction & txn, proxygen::HTTPMessage * msg) Line 25 C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTPDownstreamSession::setupOnHeadersComplete(proxygen::HTTPTransaction * txn, proxygen::HTTPMessage * msg) Line 50   C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTPSession::onHeadersComplete(unsigned __int64 streamID, std::unique_ptr<proxygen::HTTPMessage,std::default_delete<proxygen::HTTPMessage>> msg) Line 892 C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTPChecks::onHeadersComplete(unsigned __int64 stream, std::unique_ptr<proxygen::HTTPMessage,std::default_delete<proxygen::HTTPMessage>> msg) Line 32 C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTP1xCodec::onHeadersComplete(unsigned __int64 len) Line 1216    C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTP1xCodec::onHeadersCompleteCB(proxygen::http_parser * parser, const char * __formal, unsigned __int64 len) Line 1395   C++ Symbols loaded.
    ProxyServer.exe!proxygen::http_parser_execute_options(proxygen::http_parser * parser, const proxygen::http_parser_settings * settings, unsigned char options, const char * data, unsigned __int64 len) Line 1897    C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTP1xCodec::onIngressImpl(const folly::IOBuf & buf) Line 224 C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTP1xCodec::onIngress(const folly::IOBuf & buf) Line 184 C++ Symbols loaded.
    ProxyServer.exe!proxygen::PassThroughHTTPCodecFilter::onIngress(const folly::IOBuf & buf) Line 203  C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTPSession::processReadData() Line 531   C++ Symbols loaded.
    ProxyServer.exe!proxygen::HTTPSession::readDataAvailable(unsigned __int64 readSize) Line 484    C++ Symbols loaded.
    ProxyServer.exe!folly::AsyncSocket::processNormalRead() Line 2995   C++ Symbols loaded.
    ProxyServer.exe!folly::AsyncSocket::handleRead() Line 3064  C++ Symbols loaded.
    ProxyServer.exe!folly::AsyncSocket::ioReady(unsigned short events) Line 2410    C++ Symbols loaded.
    ProxyServer.exe!folly::AsyncSocket::IoHandler::handlerReady(unsigned short events) Line 1299    C++ Symbols loaded.
    ProxyServer.exe!folly::EventHandler::libeventCallback(__int64 fd, short events, void * arg) Line 161    C++ Symbols loaded.
    event_cored.dll!event_persist_closure(event_base * base, event * ev) Line 1660  C   Symbols loaded.
    event_cored.dll!event_process_active_single_queue(event_base * base, evcallback_list * activeq, int max_to_process, const timeval * endtime) Line 1719  C   Symbols loaded.
    event_cored.dll!event_process_active(event_base * base) Line 1819   C   Symbols loaded.
    event_cored.dll!event_base_loop(event_base * base, int flags) Line 2068 C   Symbols loaded.
    ProxyServer.exe!`anonymous namespace'::EventBaseBackend::eb_event_base_loop(int flags) Line 75  C++ Symbols loaded.
    ProxyServer.exe!folly::EventBase::loopMain(int flags, bool ignoreKeepAlive) Line 400    C++ Symbols loaded.
    ProxyServer.exe!folly::EventBase::loopBody(int flags, bool ignoreKeepAlive) Line 326    C++ Symbols loaded.
    ProxyServer.exe!folly::EventBase::loop() Line 305   C++ Symbols loaded.
    ProxyServer.exe!folly::EventBase::loopForever() Line 545    C++ Symbols loaded.
    ProxyServer.exe!folly::IOThreadPoolExecutor::threadRun(std::shared_ptr<folly::ThreadPoolExecutor::Thread> thread) Line 251  C++ Symbols loaded.
    ProxyServer.exe!std::invoke<void (__cdecl folly::ThreadPoolExecutor::*&)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>),folly::ThreadPoolExecutor * &,std::shared_ptr<folly::ThreadPoolExecutor::Thread> &>(void(folly::ThreadPoolExecutor::*)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>) & _Obj, folly::ThreadPoolExecutor * & _Arg1, std::shared_ptr<folly::ThreadPoolExecutor::Thread> & <_Args2_0>) Line 1601 C++ Symbols loaded.
    ProxyServer.exe!std::_Invoker_ret<std::_Unforced>::_Call<void (__cdecl folly::ThreadPoolExecutor::*&)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>),folly::ThreadPoolExecutor * &,std::shared_ptr<folly::ThreadPoolExecutor::Thread> &>(void(folly::ThreadPoolExecutor::*)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>) & _Func, folly::ThreadPoolExecutor * & <_Vals_0>, std::shared_ptr<folly::ThreadPoolExecutor::Thread> & <_Vals_1>) Line 671 C++ Symbols loaded.
    ProxyServer.exe!std::_Call_binder<std::_Unforced,0,1,void (__cdecl folly::ThreadPoolExecutor::*)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>),std::tuple<folly::ThreadPoolExecutor *,std::shared_ptr<folly::ThreadPoolExecutor::Thread>>,std::tuple<>>(std::_Invoker_ret<std::_Unforced> __formal, std::integer_sequence<unsigned __int64,0,1> __formal, void(folly::ThreadPoolExecutor::*)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>) & _Obj, std::tuple<folly::ThreadPoolExecutor *,std::shared_ptr<folly::ThreadPoolExecutor::Thread>> & _Tpl, std::tuple<> && _Ut) Line 1963    C++ Symbols loaded.
    ProxyServer.exe!std::_Binder<std::_Unforced,void (__cdecl folly::ThreadPoolExecutor::*)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>),folly::ThreadPoolExecutor *,std::shared_ptr<folly::ThreadPoolExecutor::Thread> &>::operator()<>() Line 2000 C++ Symbols loaded.
    ProxyServer.exe!folly::detail::function::FunctionTraits<void __cdecl(void)>::callSmall<std::_Binder<std::_Unforced,void (__cdecl folly::ThreadPoolExecutor::*)(std::shared_ptr<folly::ThreadPoolExecutor::Thread>),folly::ThreadPoolExecutor *,std::shared_ptr<folly::ThreadPoolExecutor::Thread> &>>(folly::detail::function::Data & p) Line 353   C++ Symbols loaded.
    ProxyServer.exe!std::thread::_Invoke<std::tuple<`folly::NamedThreadFactory::newThread'::`2'::<lambda_1>>,0>(void * _RawVals) Line 56    C++ Symbols loaded.
    ucrtbased.dll!00007ffc2ec13010()    Unknown No symbols loaded.
    kernel32.dll!00007ffc74b27614() Unknown No symbols loaded.
    ntdll.dll!RtlUserThreadStart() Unknown Symbols loaded.

Image of the Memory Access Violation Exception thrown. Exception.png

What causes the error and how to fix it and implement my own connector? Please help me with this issue.

afrind commented 1 year ago

This sounds very strange, especially since neither HTTPConnector nor your replacement appear in the stack trace that I can see. getPeerAddress just copies the address from the underlying HTTPSession.

Can you explain why you need to write your own connector (eg: what is missing in the existing class)?

SteveSelva commented 1 year ago

Yeah, its kind of weird. It was working well and all of sudden this exception is thrown when I restart the PC. And I don't know how peerAddr_ becomes NULL which was copied during the construction of proxygen::HTTPSession.

Is there any way that peerAddr_ can become NULL?

I am implementing my own connector to handle CONNECT requests. (HTTPS proxy).

afrind commented 1 year ago

Is there any way that peerAddr_ can become NULL?

I don't think so? It's not even a pointer, folly::SocketAddress is a member of the session.

SteveSelva commented 1 year ago

This is the exception being thrown and the local data at that time. image

I don't know what's happening. Can you help me fix this please.

SteveSelva commented 1 year ago

Now, I removed the connector and it worked fine. After that, I extended proxygen::SessionPool and made my own implementation of fetching Sessions from session lists. This again caused the same error. Don't know what is causing this issue, do you know why?