// Carries out the command, possibly by sending it to the server. // If the client is controlled via the API, the setClientOuput method // is invoked to update the client with the command output for access // via the API. void DebuggerCommand::onClient(DebuggerClient &client) { TRACE(2, "DebuggerCommand::onClient\n"); onClientImpl(client); if (client.isApiMode() && !m_incomplete) { setClientOutput(client); } }
void CmdWhere::onClientImpl(DebuggerClient &client) { if (DebuggerCommand::displayedHelp(client)) return; if (client.argCount() > 1) { help(client); return; } Array st = fetchStackTrace(client); if (st.empty()) { client.info("(no stacktrace to display or in global scope)"); client.info("if you hit serialization limit, consider do " "\"set sa off\" and then get the stack without args"); return; } // so list command can default to current frame client.moveToFrame(client.getFrame(), false); if (client.argCount() == 0) { int i = 0; for (ArrayIter iter(st); iter; ++iter) { client.printFrame(i, iter.second().toArray()); ++i; if (!client.isApiMode() && i % DebuggerClient::ScrollBlockSize == 0 && client.ask("There are %zd more frames. Continue? [Y/n]", st.size() - i) == 'n') { break; } } } else { string snum = client.argValue(1); int num = atoi(snum.c_str()); if (snum[0] == '-') { snum = snum.substr(1); } if (!DebuggerClient::IsValidNumber(snum)) { client.error("The argument, if specified, has to be numeric."); return; } if (num > 0) { for (int i = 0; i < num && i < st.size(); i++) { client.printFrame(i, st[i].toArray()); } } else if (num < 0) { for (int i = st.size() + num; i < st.size(); i++) { client.printFrame(i, st[i].toArray()); } } else { client.error("0 was specified for the number of frames"); client.tutorial( "The optional argument is the number of frames to print out. " "Use a positive number to print out innermost frames. Use a negative " "number to print out outermost frames." ); } } }
void CmdPrint::onClientImpl(DebuggerClient &client) { if (DebuggerCommand::displayedHelp(client)) return; if (client.argCount() == 0) { help(client); return; } int index = 1; if (client.arg(1, "always")) { m_isForWatch = true; if (client.argCount() == 1) { client.error("'[p]rint [a]lways' needs an expression to watch."); return; } index++; } else if (client.arg(1, "list")) { m_isForWatch = true; processList(client); return; } else if (client.arg(1, "clear")) { m_isForWatch = true; processClear(client); return; } const char *format = nullptr; for (const char **fmt = Formats; *fmt; fmt++) { if (client.arg(index, *fmt)) { format = *fmt; index++; break; } } m_body = client.lineRest(index); if (m_isForWatch) { client.addWatch(format, m_body); return; } m_bypassAccessCheck = client.getDebuggerBypassCheck(); m_printLevel = client.getDebuggerPrintLevel(); assert(m_printLevel <= 0 || m_printLevel >= DebuggerClient::MinPrintLevel); m_frame = client.getFrame(); CmdPrintPtr res = client.xend<CmdPrint>(this); if (!res->is(m_type)) { assert(client.isApiMode()); m_incomplete = true; res->setClientOutput(client); } else { m_output = res->m_output; m_ret = res->m_ret; if (!m_output.empty()) { client.output(m_output); } client.output(FormatResult(format, m_ret)); } }
void CmdEval::onClientImpl(DebuggerClient &client) { m_body = client.getCode(); m_frame = client.getFrame(); m_bypassAccessCheck = client.getDebuggerBypassCheck(); DebuggerCommandPtr res = client.xendWithNestedExecution<DebuggerCommand>(this); if (!res->is(m_type)) { assert(client.isApiMode()); m_incomplete = true; res->setClientOutput(client); } else { res->handleReply(client); } }
void CmdEval::onClientImpl(DebuggerClient &client) { m_body = client.getCode(); m_frame = client.getFrame(); m_bypassAccessCheck = client.getDebuggerBypassCheck(); client.sendToServer(this); DebuggerCommandPtr res = client.recvFromServer(m_type); if (!res->is(m_type)) { assert(client.isApiMode()); m_incomplete = true; res->setClientOutput(client); } else { res->handleReply(client); } }
bool CmdMachine::AttachSandbox(DebuggerClient &client, const char *user /* = NULL */, const char *name /* = NULL */, bool force /* = false */) { string login; if (user == nullptr) { user = client.getCurrentUser().c_str(); } if (client.isApiMode()) { force = true; } DSandboxInfoPtr sandbox(new DSandboxInfo()); sandbox->m_user = user ? user : ""; sandbox->m_name = (name && *name) ? name : "default"; return AttachSandbox(client, sandbox, force); }
void CmdInterrupt::onClientImpl(DebuggerClient &client) { client.setCurrentLocation(m_threadId, m_bpi); if (!client.getDebuggerClientSmallStep()) { // Adjust line and char if it's not small stepping if (m_bpi->m_line1 == m_bpi->m_line2) { m_bpi->m_char1 = 1; m_bpi->m_char2 = 100; } } client.setMatchedBreakPoints(m_matched); switch (m_interrupt) { case SessionStarted: if (!m_program.empty()) { client.info("Program %s loaded. Type '[r]un' or '[c]ontinue' to go.", m_program.c_str()); m_bpi->m_file = m_program; } break; case SessionEnded: if (!m_program.empty()) { client.info("Program %s exited normally.", m_program.c_str()); } break; case RequestStarted: if (!m_program.empty()) { client.info("Web request %s started.", m_program.c_str()); } break; case RequestEnded: if (!m_program.empty()) { client.info("Web request %s ended.", m_program.c_str()); } break; case PSPEnded: if (!m_program.empty()) { client.info("Post-Send Processing for %s was ended.", m_program.c_str()); } break; case HardBreakPoint: case BreakPointReached: case ExceptionThrown: { bool found = false; bool toggled = false; BreakPointInfoPtrVec *bps = client.getBreakPoints(); for (unsigned int i = 0; i < m_matched.size(); i++) { BreakPointInfoPtr bpm = m_matched[i]; BreakPointInfoPtr bp; int index = 0; for (; index < (int)bps->size(); index++) { if (bpm->same((*bps)[index])) { bp = (*bps)[index]; break; } } if (bp) { found = true; if (bp->m_state == BreakPointInfo::Once) { bp->m_state = BreakPointInfo::Disabled; toggled = true; } if (m_interrupt == BreakPointReached || m_interrupt == HardBreakPoint) { client.info("Breakpoint %d reached %s", bp->index(), m_bpi->site().c_str()); client.shortCode(m_bpi); } else { if (m_bpi->m_exceptionClass == BreakPointInfo::ErrorClassName) { client.info("Breakpoint %d reached: An error occurred %s", bp->index(), m_bpi->site().c_str()); client.shortCode(m_bpi); client.error("Error Message: %s", m_bpi->m_exceptionObject.c_str()); } else { client.info("Breakpoint %d reached: Throwing %s %s", bp->index(), m_bpi->m_exceptionClass.c_str(), m_bpi->site().c_str()); client.shortCode(m_bpi); if (client.isApiMode() || client.getLogFileHandler()) { client.output(m_bpi->m_exceptionObject); } } } if (!bpm->m_output.empty()) { client.print(bpm->m_output); } } } if (toggled) { CmdBreak::SendClientBreakpointListToServer(client); } if (!found) { if (m_interrupt == HardBreakPoint) { // for HardBreakPoint, default the frame to the caller client.setFrame(1); } client.info("Break %s", m_bpi->site().c_str()); client.shortCode(m_bpi); } break; } } if (!m_errorMsg.empty()) { client.error(m_errorMsg); } // watches switch (m_interrupt) { case SessionStarted: case RequestStarted: break; default: { DebuggerClient::WatchPtrVec &watches = client.getWatches(); for (int i = 0; i < (int)watches.size(); i++) { if (i > 0) client.output(""); client.info("Watch %d: %s =", i + 1, watches[i]->second.c_str()); Variant v = CmdPrint().processWatch(client, watches[i]->first, watches[i]->second); client.output(CmdPrint::FormatResult(watches[i]->first, v)); } } } }