// Always called from recv and implements specific // logic for deserializing a list command received via Thrift. void CmdList::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_file); thrift.read(m_line1); thrift.read(m_line2); thrift.read(m_code); }
void CmdMachine::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_sandboxes); thrift.read(m_rpcConfig); thrift.read(m_force); thrift.read(m_succeed); }
void CmdPrint::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_ret); thrift.read(m_output); thrift.read(m_frame); thrift.read(m_bypassAccessCheck); thrift.read(m_printLevel); }
void InstPointInfo::recvImpl(DebuggerThriftBuffer &thrift) { TRACE(2, "InstPointInfo::recvImpl\n"); thrift.read(m_locType); thrift.read(m_valid); thrift.read(m_file); thrift.read(m_line); thrift.read(m_func); thrift.read(m_desc); thrift.read(m_code); }
void CmdWhere::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); { String sdata; thrift.read(sdata); if (DebuggerWireHelpers::WireUnserialize(sdata, m_stacktrace) != DebuggerWireHelpers::NoError) { m_stacktrace = null_array; m_wireError = sdata; } } thrift.read(m_stackArgs); }
void CmdVariable::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_frame); { String sdata; thrift.read(sdata); if (DebuggerWireHelpers::WireUnserialize(sdata, m_variables) != DebuggerWireHelpers::NoError) { m_variables = null_array; m_wireError = sdata; } } thrift.read(m_global); }
void CmdEval::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_output); thrift.read(m_frame); thrift.read(m_bypassAccessCheck); if (this->m_version == 2) thrift.read(m_failed); // Old senders will set version to 0. A new sender sets it to 1 // and then expects an answer using version 2. // Note that version 1 is the same format as version 0, so old // receivers will not break when receiving a version 1 message. // This code ensures that version 2 messages are received only // by receivers that previously sent a version 1 message (thus // indicating their ability to deal with version 2 messages). if (this->m_version == 1) this->m_version = 2; }
void InstPointInfo::RecvImpl(InstPointInfoPtrVec& ips, DebuggerThriftBuffer &thrift) { TRACE(2, "InstPointInfo::RecvImpl\n"); int16_t size; thrift.read(size); ips.resize(size); for (int i = 0; i < size; i++) { InstPointInfoPtr ipi(new InstPointInfo()); ipi->recvImpl(thrift); ips[i] = ipi; } }
void CmdVariable::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_frame); { String sdata; thrift.read(sdata); auto error = DebuggerWireHelpers::WireUnserialize(sdata, m_variables); if (error != DebuggerWireHelpers::NoError) { m_variables = null_array; if (error != DebuggerWireHelpers::HitLimit || m_version == 0) { // Unexpected error. Log it. m_wireError = sdata; } } } thrift.read(m_global); if (m_version == 2) { thrift.read(m_varName); thrift.read(m_filter); } }
void CmdPrint::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); { String sdata; thrift.read(sdata); int error = DebuggerWireHelpers::WireUnserialize(sdata, m_ret); if (error) { m_ret = null; } if (error == DebuggerWireHelpers::HitLimit) { m_wireError = "Hit unserialization limit. " "Try with smaller print level"; } } thrift.read(m_output); thrift.read(m_frame); thrift.read(m_bypassAccessCheck); thrift.read(m_printLevel); thrift.read(m_noBreak); }
void CmdRun::recvImpl(DebuggerThriftBuffer &thrift) { TRACE(2, "CmdRun::recvImpl\n"); DebuggerCommand::recvImpl(thrift); m_args = std::make_shared<std::vector<std::string>>(); thrift.read(*m_args); }
void CmdThread::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_out); thrift.read(m_threads); }
void CmdSignal::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_signum); }
void CmdGlobal::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_globals); if (m_version == 1) m_version = 2; }
void CmdVariable::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_frame); thrift.read(m_variables); thrift.read(m_global); }
void CmdInstrument::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_type); thrift.read(m_enabled); InstPointInfo::RecvImpl(m_ips, thrift); }
void CmdInterrupt::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_interrupt); thrift.read(m_program); thrift.read(m_errorMsg); thrift.read(m_threadId); thrift.read(m_pendingJump); m_bpi = BreakPointInfoPtr(new BreakPointInfo()); bool site; thrift.read(site); if (site) { thrift.read(m_bpi->m_file); thrift.read(m_bpi->m_line1); thrift.read(m_bpi->m_char1); thrift.read(m_bpi->m_line2); thrift.read(m_bpi->m_char2); DFunctionInfoPtr func(new DFunctionInfo()); thrift.read(func->m_namespace); thrift.read(func->m_class); thrift.read(func->m_function); m_bpi->m_funcs.push_back(func); thrift.read(m_bpi->m_exceptionClass); thrift.read(m_bpi->m_exceptionObject); } BreakPointInfo::RecvImpl(m_matched, thrift); }
void CmdUser::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_cmd); }
void CmdWhere::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_stacktrace); }
bool DebuggerCommand::Receive(DebuggerThriftBuffer &thrift, DebuggerCommandPtr &cmd, const char *caller) { cmd.reset(); struct pollfd fds[1]; fds[0].fd = thrift.getSocket()->fd(); fds[0].events = POLLIN|POLLERR|POLLHUP; int ret = poll(fds, 1, POLLING_SECONDS * 1000); if (ret == 0) { return false; } if (ret == -1 || !(fds[0].revents & POLLIN)) { return errno != EINTR; // treat signals as timeouts } int32 type; string clsname; try { thrift.reset(true); thrift.read(type); thrift.read(clsname); } catch (...) { Logger::Verbose("%s => DebuggerCommand::Receive(): socket error", caller); return true; } // not all commands are here, as not all commands need to be sent over wire switch (type) { case KindOfBreak : cmd = DebuggerCommandPtr(new CmdBreak ()); break; case KindOfContinue : cmd = DebuggerCommandPtr(new CmdContinue ()); break; case KindOfDown : cmd = DebuggerCommandPtr(new CmdDown ()); break; case KindOfException: cmd = DebuggerCommandPtr(new CmdException()); break; case KindOfFrame : cmd = DebuggerCommandPtr(new CmdFrame ()); break; case KindOfGlobal : cmd = DebuggerCommandPtr(new CmdGlobal ()); break; case KindOfInfo : cmd = DebuggerCommandPtr(new CmdInfo ()); break; case KindOfJump : cmd = DebuggerCommandPtr(new CmdJump ()); break; case KindOfConstant : cmd = DebuggerCommandPtr(new CmdConstant ()); break; case KindOfList : cmd = DebuggerCommandPtr(new CmdList ()); break; case KindOfMachine : cmd = DebuggerCommandPtr(new CmdMachine ()); break; case KindOfNext : cmd = DebuggerCommandPtr(new CmdNext ()); break; case KindOfOut : cmd = DebuggerCommandPtr(new CmdOut ()); break; case KindOfPrint : cmd = DebuggerCommandPtr(new CmdPrint ()); break; case KindOfQuit : cmd = DebuggerCommandPtr(new CmdQuit ()); break; case KindOfRun : cmd = DebuggerCommandPtr(new CmdRun ()); break; case KindOfStep : cmd = DebuggerCommandPtr(new CmdStep ()); break; case KindOfThread : cmd = DebuggerCommandPtr(new CmdThread ()); break; case KindOfUp : cmd = DebuggerCommandPtr(new CmdUp ()); break; case KindOfVariable : cmd = DebuggerCommandPtr(new CmdVariable ()); break; case KindOfWhere : cmd = DebuggerCommandPtr(new CmdWhere ()); break; case KindOfUser : cmd = DebuggerCommandPtr(new CmdUser ()); break; case KindOfEval : cmd = DebuggerCommandPtr(new CmdEval ()); break; case KindOfInterrupt: cmd = DebuggerCommandPtr(new CmdInterrupt()); break; case KindOfSignal : cmd = DebuggerCommandPtr(new CmdSignal ()); break; case KindOfShell : cmd = DebuggerCommandPtr(new CmdShell ()); break; case KindOfExtended: { ASSERT(!clsname.empty()); cmd = CmdExtended::CreateExtendedCommand(clsname); ASSERT(cmd); break; } default: ASSERT(false); Logger::Error("%s => DebuggerCommand::Receive(): bad cmd type: %d", caller, type); return true; } if (!cmd->recv(thrift)) { cmd.reset(); } return true; }
void DebuggerCommand::recvImpl(DebuggerThriftBuffer &thrift) { thrift.read(m_body); thrift.read(m_version); }
void CmdFlowControl::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_count); }
void CmdInterrupt::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_interrupt); thrift.read(m_program); thrift.read(m_errorMsg); thrift.read(m_threadId); // Used to be m_pendingJump, but that's been removed. Read a dummy bool until // we rev the protocol. bool dummy; thrift.read(dummy); m_bpi = std::make_shared<BreakPointInfo>(); bool site; thrift.read(site); if (site) { thrift.read(m_bpi->m_file); thrift.read(m_bpi->m_line1); thrift.read(m_bpi->m_char1); thrift.read(m_bpi->m_line2); thrift.read(m_bpi->m_char2); auto func = std::make_shared<DFunctionInfo>(); thrift.read(func->m_namespace); thrift.read(func->m_class); thrift.read(func->m_function); m_bpi->m_funcs.push_back(func); thrift.read(m_bpi->m_exceptionClass); thrift.read(m_bpi->m_exceptionObject); } BreakPointInfo::RecvImpl(0, m_matched, thrift); }
void CmdShell::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_args); thrift.read(m_out); }
void CmdExample::recvImpl(DebuggerThriftBuffer &thrift) { CmdExtended::recvImpl(thrift); thrift.read(m_input); thrift.read(m_output); }
void CmdRun::recvImpl(DebuggerThriftBuffer &thrift) { TRACE(2, "CmdRun::recvImpl\n"); DebuggerCommand::recvImpl(thrift); m_args = StringVecPtr(new StringVec()); thrift.read(*m_args); }
void CmdInternalTesting::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_arg); thrift.read(m_unused); }
void CmdExtension::recvImpl(DebuggerThriftBuffer &thrift) { CmdExtended::recvImpl(thrift); thrift.read(m_args); thrift.read(m_out); thrift.read(m_err); }
void CmdHeaptrace::recvImpl(DebuggerThriftBuffer &thrift) { DebuggerCommand::recvImpl(thrift); thrift.read(m_accum.typesMap); thrift.read(m_accum.sizeMap); thrift.read(m_accum.adjacencyList); }
// Returns false on timeout, true when data has been read even if that data // didn't form a usable command. Is there is no usable command, cmd is null. bool DebuggerCommand::Receive(DebuggerThriftBuffer &thrift, DebuggerCommandPtr &cmd, const char *caller) { TRACE(5, "DebuggerCommand::Receive\n"); cmd.reset(); struct pollfd fds[1]; fds[0].fd = thrift.getSocket()->fd(); fds[0].events = POLLIN|POLLERR|POLLHUP; int ret = poll(fds, 1, POLLING_SECONDS * 1000); if (ret == 0) return false; // Timeout if (ret == -1) { auto errorNumber = errno; // Just in case TRACE_RB changes errno TRACE_RB(1, "DebuggerCommand::Receive: error %d\n", errorNumber); return errorNumber != EINTR; // Treat signals as timeouts } // If we don't have any data to read (POLLIN) then we're done. If we // do have data we'll attempt to read and decode it below, even if // there are other error bits set. if (!(fds[0].revents & POLLIN)) { TRACE_RB(1, "DebuggerCommand::Receive: revents %d\n", fds[0].revents); return true; } int32_t type; std::string clsname; try { thrift.reset(true); thrift.read(type); thrift.read(clsname); } catch (...) { // Note: this error case is difficult to test. But, it's exactly the same // as the error noted below. Make sure to keep handling of both of these // errors in sync. TRACE_RB(1, "%s: socket error receiving command", caller); return true; } TRACE(1, "DebuggerCommand::Receive: got cmd of type %d\n", type); // not all commands are here, as not all commands need to be sent over wire switch (type) { case KindOfBreak : cmd = DebuggerCommandPtr(new CmdBreak ()); break; case KindOfContinue : cmd = DebuggerCommandPtr(new CmdContinue ()); break; case KindOfDown : cmd = DebuggerCommandPtr(new CmdDown ()); break; case KindOfException: cmd = DebuggerCommandPtr(new CmdException()); break; case KindOfFrame : cmd = DebuggerCommandPtr(new CmdFrame ()); break; case KindOfGlobal : cmd = DebuggerCommandPtr(new CmdGlobal ()); break; case KindOfInfo : cmd = DebuggerCommandPtr(new CmdInfo ()); break; case KindOfConstant : cmd = DebuggerCommandPtr(new CmdConstant ()); break; case KindOfList : cmd = DebuggerCommandPtr(new CmdList ()); break; case KindOfMachine : cmd = DebuggerCommandPtr(new CmdMachine ()); break; case KindOfNext : cmd = DebuggerCommandPtr(new CmdNext ()); break; case KindOfOut : cmd = DebuggerCommandPtr(new CmdOut ()); break; case KindOfPrint : cmd = DebuggerCommandPtr(new CmdPrint ()); break; case KindOfQuit : cmd = DebuggerCommandPtr(new CmdQuit ()); break; case KindOfRun : cmd = DebuggerCommandPtr(new CmdRun ()); break; case KindOfStep : cmd = DebuggerCommandPtr(new CmdStep ()); break; case KindOfThread : cmd = DebuggerCommandPtr(new CmdThread ()); break; case KindOfUp : cmd = DebuggerCommandPtr(new CmdUp ()); break; case KindOfVariable : cmd = DebuggerCommandPtr(new CmdVariable ()); break; case KindOfVariableAsync : cmd = DebuggerCommandPtr(new CmdVariable (KindOfVariableAsync)); break; case KindOfWhere : cmd = DebuggerCommandPtr(new CmdWhere ()); break; case KindOfWhereAsync: cmd = DebuggerCommandPtr(new CmdWhere(KindOfWhereAsync)); break; case KindOfEval : cmd = DebuggerCommandPtr(new CmdEval ()); break; case KindOfInterrupt: cmd = DebuggerCommandPtr(new CmdInterrupt()); break; case KindOfSignal : cmd = DebuggerCommandPtr(new CmdSignal ()); break; case KindOfShell : cmd = DebuggerCommandPtr(new CmdShell ()); break; case KindOfInternalTesting : cmd = DebuggerCommandPtr(new CmdInternalTesting()); break; case KindOfExtended: { assert(!clsname.empty()); cmd = CmdExtended::CreateExtendedCommand(clsname); assert(cmd); break; } default: TRACE_RB(1, "%s: received bad cmd type: %d", caller, type); cmd.reset(); return true; } if (!cmd->recv(thrift)) { // Note: this error case is easily tested, and we have a test for it. But // the error case noted above is quite difficult to test. Keep these two // in sync. TRACE_RB(1, "%s: socket error receiving command", caller); cmd.reset(); } return true; }