DBG+GUI: implemented trace switch condition
This commit is contained in:
parent
6f92218437
commit
9f7f649f7e
|
@ -9,7 +9,7 @@
|
|||
|
||||
extern std::vector<std::pair<duint, duint>> RunToUserCodeBreakpoints;
|
||||
|
||||
static bool cbDebugConditionalTrace(void* callBack, bool stepOver, int argc, char* argv[])
|
||||
static bool cbDebugConditionalTrace(void(*callback)(), bool stepOver, int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return false;
|
||||
|
@ -29,21 +29,22 @@ static bool cbDebugConditionalTrace(void* callBack, bool stepOver, int argc, cha
|
|||
return false;
|
||||
}
|
||||
HistoryClear();
|
||||
|
||||
if(stepOver)
|
||||
StepOver(callBack);
|
||||
StepOver((void*)callback);
|
||||
else
|
||||
StepIntoWow64(callBack);
|
||||
StepIntoWow64((void*)callback);
|
||||
return cbDebugRunInternal(argc, argv);
|
||||
}
|
||||
|
||||
bool cbDebugTraceIntoConditional(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugConditionalTrace((void*)cbTraceIntoConditionalStep, false, argc, argv);
|
||||
return cbDebugConditionalTrace(cbTraceIntoConditionalStep, false, argc, argv);
|
||||
}
|
||||
|
||||
bool cbDebugTraceOverConditional(int argc, char* argv[])
|
||||
{
|
||||
return cbDebugConditionalTrace((void*)cbTraceOverConditionalStep, true, argc, argv);
|
||||
return cbDebugConditionalTrace(cbTraceOverConditionalStep, true, argc, argv);
|
||||
}
|
||||
|
||||
bool cbDebugTraceIntoBeyondTraceRecord(int argc, char* argv[])
|
||||
|
@ -51,10 +52,10 @@ bool cbDebugTraceIntoBeyondTraceRecord(int argc, char* argv[])
|
|||
if(argc == 1)
|
||||
{
|
||||
char* new_argv[] = { "tibt", "0" };
|
||||
return cbDebugConditionalTrace((void*)cbTraceIntoBeyondTraceRecordStep, false, 2, new_argv);
|
||||
return cbDebugConditionalTrace(cbTraceIntoBeyondTraceRecordStep, false, 2, new_argv);
|
||||
}
|
||||
else
|
||||
return cbDebugConditionalTrace((void*)cbTraceIntoBeyondTraceRecordStep, false, argc, argv);
|
||||
return cbDebugConditionalTrace(cbTraceIntoBeyondTraceRecordStep, false, argc, argv);
|
||||
}
|
||||
|
||||
bool cbDebugTraceOverBeyondTraceRecord(int argc, char* argv[])
|
||||
|
@ -62,10 +63,10 @@ bool cbDebugTraceOverBeyondTraceRecord(int argc, char* argv[])
|
|||
if(argc == 1)
|
||||
{
|
||||
char* new_argv[] = { "tobt", "0" };
|
||||
return cbDebugConditionalTrace((void*)cbTraceOverBeyondTraceRecordStep, true, 2, new_argv);
|
||||
return cbDebugConditionalTrace(cbTraceOverBeyondTraceRecordStep, true, 2, new_argv);
|
||||
}
|
||||
else
|
||||
return cbDebugConditionalTrace((void*)cbTraceOverBeyondTraceRecordStep, true, argc, argv);
|
||||
return cbDebugConditionalTrace(cbTraceOverBeyondTraceRecordStep, true, argc, argv);
|
||||
}
|
||||
|
||||
bool cbDebugTraceIntoIntoTraceRecord(int argc, char* argv[])
|
||||
|
@ -73,10 +74,10 @@ bool cbDebugTraceIntoIntoTraceRecord(int argc, char* argv[])
|
|||
if(argc == 1)
|
||||
{
|
||||
char* new_argv[] = { "tiit", "0" };
|
||||
return cbDebugConditionalTrace((void*)cbTraceIntoIntoTraceRecordStep, false, 2, new_argv);
|
||||
return cbDebugConditionalTrace(cbTraceIntoIntoTraceRecordStep, false, 2, new_argv);
|
||||
}
|
||||
else
|
||||
return cbDebugConditionalTrace((void*)cbTraceIntoIntoTraceRecordStep, false, argc, argv);
|
||||
return cbDebugConditionalTrace(cbTraceIntoIntoTraceRecordStep, false, argc, argv);
|
||||
}
|
||||
|
||||
bool cbDebugTraceOverIntoTraceRecord(int argc, char* argv[])
|
||||
|
@ -84,10 +85,10 @@ bool cbDebugTraceOverIntoTraceRecord(int argc, char* argv[])
|
|||
if(argc == 1)
|
||||
{
|
||||
char* new_argv[] = { "toit", "0" };
|
||||
return cbDebugConditionalTrace((void*)cbTraceOverIntoTraceRecordStep, true, 2, new_argv);
|
||||
return cbDebugConditionalTrace(cbTraceOverIntoTraceRecordStep, true, 2, new_argv);
|
||||
}
|
||||
else
|
||||
return cbDebugConditionalTrace((void*)cbTraceOverIntoTraceRecordStep, true, argc, argv);
|
||||
return cbDebugConditionalTrace(cbTraceOverIntoTraceRecordStep, true, argc, argv);
|
||||
}
|
||||
|
||||
bool cbDebugRunToParty(int argc, char* argv[])
|
||||
|
@ -149,3 +150,15 @@ bool cbDebugTraceSetCommand(int argc, char* argv[])
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cbDebugTraceSetSwitchCondition(int argc, char* argv[])
|
||||
{
|
||||
auto condition = argc > 1 ? argv[1] : "";
|
||||
dputs(condition);
|
||||
if(!dbgsettraceswitchcondition(condition))
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid expression \"%s\"\n"), condition);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,4 +11,5 @@ bool cbDebugTraceOverIntoTraceRecord(int argc, char* argv[]);
|
|||
bool cbDebugRunToParty(int argc, char* argv[]);
|
||||
bool cbDebugRunToUserCode(int argc, char* argv[]);
|
||||
bool cbDebugTraceSetLog(int argc, char* argv[]);
|
||||
bool cbDebugTraceSetCommand(int argc, char* argv[]);
|
||||
bool cbDebugTraceSetCommand(int argc, char* argv[]);
|
||||
bool cbDebugTraceSetSwitchCondition(int argc, char* argv[]);
|
|
@ -135,6 +135,21 @@ struct TraceState
|
|||
return cmdCondition ? cmdCondition->text : emptyString;
|
||||
}
|
||||
|
||||
bool InitSwitchCondition(const String & expression)
|
||||
{
|
||||
delete switchCondition;
|
||||
switchCondition = nullptr;
|
||||
if(expression.empty())
|
||||
return true;
|
||||
switchCondition = new TextCondition(expression, "");
|
||||
return switchCondition->condition.IsValidExpression();
|
||||
}
|
||||
|
||||
bool EvaluateSwitch(bool defaultValue) const
|
||||
{
|
||||
return switchCondition && switchCondition->Evaluate(defaultValue);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
delete traceCondition;
|
||||
|
@ -143,12 +158,15 @@ struct TraceState
|
|||
logCondition = nullptr;
|
||||
delete cmdCondition;
|
||||
cmdCondition = nullptr;
|
||||
delete switchCondition;
|
||||
switchCondition = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
TraceCondition* traceCondition = nullptr;
|
||||
TextCondition* logCondition = nullptr;
|
||||
TextCondition* cmdCondition = nullptr;
|
||||
TextCondition* switchCondition = nullptr;
|
||||
String emptyString;
|
||||
};
|
||||
|
||||
|
@ -244,6 +262,13 @@ bool dbgsettracecmd(const String & expression, const String & text)
|
|||
return traceState.InitCmdCondition(expression, text);
|
||||
}
|
||||
|
||||
bool dbgsettraceswitchcondition(const String & expression)
|
||||
{
|
||||
if(dbgtraceactive())
|
||||
return false;
|
||||
return traceState.InitSwitchCondition(expression);
|
||||
}
|
||||
|
||||
bool dbgtraceactive()
|
||||
{
|
||||
return traceState.IsActive();
|
||||
|
@ -900,7 +925,7 @@ static void cbGenericBreakpoint(BP_TYPE bptype, void* ExceptionAddress = nullptr
|
|||
//TODO: commands like run/step etc will fuck up your shit
|
||||
varset("$breakpointcondition", breakCondition ? 1 : 0, false);
|
||||
varset("$breakpointlogcondition", logCondition ? 1 : 0, true);
|
||||
_dbg_dbgcmddirectexec(bp.commandText);
|
||||
cmddirectexec(bp.commandText);
|
||||
duint script_breakcondition;
|
||||
if(varget("$breakpointcondition", &script_breakcondition, nullptr, nullptr))
|
||||
{
|
||||
|
@ -1221,6 +1246,7 @@ static void cbTraceUniversalConditionalStep(duint cip, bool bStepInto, void(*cal
|
|||
breakCondition = info.stop;
|
||||
auto logCondition = traceState.EvaluateLog(true);
|
||||
auto cmdCondition = traceState.EvaluateCmd(breakCondition);
|
||||
auto switchCondition = traceState.EvaluateSwitch(false);
|
||||
if(logCondition) //log
|
||||
{
|
||||
dprintf_untranslated("%s\n", stringformatinline(traceState.LogText()).c_str());
|
||||
|
@ -1230,10 +1256,13 @@ static void cbTraceUniversalConditionalStep(duint cip, bool bStepInto, void(*cal
|
|||
//TODO: commands like run/step etc will fuck up your shit
|
||||
varset("$tracecondition", breakCondition ? 1 : 0, false);
|
||||
varset("$tracelogcondition", logCondition ? 1 : 0, true);
|
||||
_dbg_dbgcmddirectexec(traceState.CmdText().c_str());
|
||||
varset("$traceswitchcondition", switchCondition ? 1 : 0, false);
|
||||
cmddirectexec(traceState.CmdText().c_str());
|
||||
duint script_breakcondition;
|
||||
if(varget("$tracecondition", &script_breakcondition, nullptr, nullptr))
|
||||
breakCondition = script_breakcondition != 0;
|
||||
if(varget("$traceswitchcondition", &script_breakcondition, nullptr, nullptr))
|
||||
switchCondition = script_breakcondition != 0;
|
||||
}
|
||||
if(breakCondition) //break the debugger
|
||||
{
|
||||
|
@ -1250,6 +1279,8 @@ static void cbTraceUniversalConditionalStep(duint cip, bool bStepInto, void(*cal
|
|||
{
|
||||
if(bTraceRecordEnabledDuringTrace)
|
||||
_dbg_dbgtraceexecute(cip);
|
||||
if(switchCondition) //switch (invert) the step type once
|
||||
bStepInto = !bStepInto;
|
||||
(bStepInto ? StepIntoWow64 : StepOver)(callback);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@ duint dbggetdbgevents();
|
|||
bool dbgsettracecondition(const String & expression, duint maxCount);
|
||||
bool dbgsettracelog(const String & expression, const String & text);
|
||||
bool dbgsettracecmd(const String & expression, const String & text);
|
||||
bool dbgsettraceswitchcondition(const String & expression);
|
||||
bool dbgtraceactive();
|
||||
void dbgsetdebuggeeinitscript(const char* fileName);
|
||||
const char* dbggetdebuggeeinitscript();
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include <capstone_wrapper.h>
|
||||
#include "datainst_helper.h"
|
||||
|
||||
|
||||
duint disasmback(unsigned char* data, duint base, duint size, duint ip, int n)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -84,6 +84,7 @@ void varinit()
|
|||
varnew("$tracecounter", 0, VAR_READONLY);
|
||||
varnew("$tracecondition", 0, VAR_SYSTEM);
|
||||
varnew("$tracelogcondition", 0, VAR_READONLY);
|
||||
varnew("$traceswitchcondition", 0, VAR_SYSTEM);
|
||||
|
||||
// Read-only variables
|
||||
varnew("$lastalloc", 0, VAR_READONLY); // Last memory allocation
|
||||
|
|
|
@ -219,6 +219,7 @@ static void registercommands()
|
|||
dbgcmdnew("RunToUserCode\1rtu", cbDebugRunToUserCode, true); //Run to user code
|
||||
dbgcmdnew("TraceSetLog\1SetTraceLog", cbDebugTraceSetLog, true); //Set trace log text + condition
|
||||
dbgcmdnew("TraceSetCommand\1SetTraceCommand", cbDebugTraceSetCommand, true); //Set trace command text + condition
|
||||
dbgcmdnew("TraceSetSwitchCondition\1SetTraceSwitchCondition", cbDebugTraceSetSwitchCondition, true); //Set trace switch condition
|
||||
|
||||
//thread control
|
||||
dbgcmdnew("createthread\1threadcreate\1newthread\1threadnew", cbDebugCreatethread, true); //create thread
|
||||
|
@ -769,9 +770,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
|
|||
|
||||
extern "C" DLL_EXPORT bool _dbg_dbgcmddirectexec(const char* cmd)
|
||||
{
|
||||
if(cmddirectexec(cmd) == false)
|
||||
return false;
|
||||
return true;
|
||||
return cmddirectexec(cmd);
|
||||
}
|
||||
|
||||
bool dbgisstopped()
|
||||
|
|
|
@ -18,6 +18,7 @@ SimpleTraceDialog::SimpleTraceDialog(QWidget* parent) :
|
|||
ui->editLogCondition->setPlaceholderText(tr("Example: eax == 0 && ebx == 0"));
|
||||
ui->editCommandText->setPlaceholderText(tr("Example: eax=4;StepOut"));
|
||||
ui->editCommandCondition->setPlaceholderText(tr("Example: eax == 0 && ebx == 0"));
|
||||
ui->editSwitchCondition->setPlaceholderText(tr("Example: eax == 0 && ebx == 0"));
|
||||
}
|
||||
|
||||
SimpleTraceDialog::~SimpleTraceDialog()
|
||||
|
@ -53,6 +54,12 @@ void SimpleTraceDialog::on_btnOk_clicked()
|
|||
QMessageBox::warning(this, tr("Error"), tr("Failed to set command text/condition!"));
|
||||
return;
|
||||
}
|
||||
auto switchCondition = ui->editSwitchCondition->addHistoryClear();
|
||||
if(!DbgCmdExecDirect(QString("TraceSetSwitchCondition \"%1\"").arg(escapeText(switchCondition)).toUtf8().constData()))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Error"), tr("Failed to set switch condition!"));
|
||||
return;
|
||||
}
|
||||
auto breakCondition = ui->editBreakCondition->addHistoryClear();
|
||||
auto maxTraceCount = ui->spinMaxTraceCount->value();
|
||||
if(!DbgCmdExecDirect(QString("%1 \"%2\", .%3").arg(mTraceCommand, escapeText(breakCondition)).arg(maxTraceCount).toUtf8().constData()))
|
||||
|
|
|
@ -7,78 +7,33 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>502</width>
|
||||
<height>218</height>
|
||||
<height>244</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblBreakCondition">
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="QLabel" name="lblHint">
|
||||
<property name="text">
|
||||
<string>&Break Condition:</string>
|
||||
<string>Hint: History is available in every text field with the Up/Down arrows!</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editBreakCondition</cstring>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="HistoryLineEdit" name="editBreakCondition"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblLogText">
|
||||
<property name="text">
|
||||
<string>&Log Text:</string>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="spinMaxTraceCount">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editLogText</cstring>
|
||||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="HistoryLineEdit" name="editLogText"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblLogCondition">
|
||||
<property name="text">
|
||||
<string>Lo&g Condition:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editLogCondition</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="HistoryLineEdit" name="editLogCondition"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblCommandText">
|
||||
<property name="text">
|
||||
<string>&Command Text:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editCommandText</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="HistoryLineEdit" name="editCommandText"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lblCommandCondition">
|
||||
<property name="text">
|
||||
<string>C&ommand Condition:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editCommandCondition</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="HistoryLineEdit" name="editCommandCondition"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lblMaxTraceCount">
|
||||
<property name="sizePolicy">
|
||||
|
@ -95,17 +50,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="spinMaxTraceCount">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="7" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
|
@ -151,13 +96,78 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QLabel" name="lblHint">
|
||||
<item row="0" column="1">
|
||||
<widget class="HistoryLineEdit" name="editBreakCondition"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblBreakCondition">
|
||||
<property name="text">
|
||||
<string>Hint: History is available in every text field with the Up/Down arrows!</string>
|
||||
<string>&Break Condition:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
<property name="buddy">
|
||||
<cstring>editBreakCondition</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="HistoryLineEdit" name="editLogCondition"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="HistoryLineEdit" name="editLogText"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblLogCondition">
|
||||
<property name="text">
|
||||
<string>Lo&g Condition:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editLogCondition</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblLogText">
|
||||
<property name="text">
|
||||
<string>&Log Text:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editLogText</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblCommandText">
|
||||
<property name="text">
|
||||
<string>&Command Text:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editCommandText</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lblCommandCondition">
|
||||
<property name="text">
|
||||
<string>C&ommand Condition:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editCommandCondition</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="HistoryLineEdit" name="editCommandCondition"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="HistoryLineEdit" name="editCommandText"/>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="HistoryLineEdit" name="editSwitchCondition"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="lblSwitchCondition">
|
||||
<property name="text">
|
||||
<string>Switch Condition:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -189,11 +199,11 @@
|
|||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>497</x>
|
||||
<y>154</y>
|
||||
<x>491</x>
|
||||
<y>214</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>524</x>
|
||||
<x>501</x>
|
||||
<y>153</y>
|
||||
</hint>
|
||||
</hints>
|
||||
|
|
Loading…
Reference in New Issue