The problem: I need to make a script or an expression that that doesn't break if somewhere on callstack is a function with a specific name.
Specific question: How can I get functions on callstack to a list of strings ?
Example:
Module!MyFunctionWithConditionalBreakpoint
Module!Function1
Module!Function2
Module!Function3
Module!MyFunctionWithConditionalBreakpoint
Module!Function1
Module!ClassA:MemberFunction
Module!Function3
I want Module!MyFunctionWithConditionalBreakpoint to break only if the call cames from Module!ClassA:MemberFunction
I need this in unmanaged code. Managed solution is something like
System.Diagnostics.StackTrace().ToString().Contains("YourMethodName")
In WinDbg you may set a conditional breakpoint using special $spat function:
bp Module!MyFunctionWithConditionalBreakpoint "r $t0 = 0;.foreach (v { k }) { .if ($spat(\"v\", \"*Module!ClassA:MemberFunction*\")) { r $t0 = 1;.break } }; .if($t0 = 0) { gc }"
In pseudo-code it will be something like:
t0 = 0
foreach (token in k-command result) {
if (token.contains("Module!ClassA:MemberFunction")) {
t0 = 1
break
}
}
if (t0 == 0) {
// continue execution
} else {
// break into the debugger
}
Why not set a breakpoint on entering Module!ClassA:MemberFunction to enable a breakpoint for Module!MyFunctionWithConditionalBreakpoint and upon leaving Module!ClassA:MemberFunction disabling it?
Related
When running the simulation in omnet++ 5.7 the execution stops suddenly and closes.
This is the code that is being run in omnet
auto simulation = getSimulation();
for (i = 1; i <= simulation->getLastComponentId(); i++) {
int x, y, id;
//scan the simulation module vector
mod = (cModule*)simulation->getModule(i);
if (strcmp(mod->getName(), "node") == 0) {
id = ((Node*)mod)->myId;
x = ((Node*)mod)->xpos;
y = ((Node*)mod)->ypos;
nodePtr[id] = ((Node*)mod);
if (id != this->myId) {
cGate* g;
char gName1[32], gName2[32];
// make new gate here
if (this->hasGate(gName1)) {
this->gate(gName1)->disconnect();
this->deleteGate(gName1);
}
this->addGate(gName1, cGate::OUTPUT, false);
// make new gate at other side
if (mod->hasGate(gName2)) {
mod->gate(gName2)->disconnect();
mod->deleteGate(gName2);
}
mod->addGate(gName2, omnetpp::cGate::INPUT, false);
//CHANNEL
cIdealChannel* ch = NULL;
this->gate(gName1)->connectTo(mod->gate(gName2), ch);
g = this->gate(gName1);
g->setDisplayString(g->getDisplayString());
}
}
}
I assume that the last line g->setDisplayString(g->getDisplayString()); is probably where the code breaks. The code repeats in the for loop with i<= simulation->getLastComponentId(). I'm new to Omnet++. Any suggestion to fix this would be helpful.
Thanks.
Several things in your code may be source of crashing:
getModule(i) may return nullptr, see OMNeT++ Simulation API, so you should check in the code whether result is not nullptr.
gName1 and gName2 are not set!
Other issues:
instead of (Node*)mod use dynamic_cast<Node*)>(mod) and check whether results is not nullptr.
instead of strcmp(mod->getName(), "node") == 0 I advice using mod->isName("node") - see OMNeT++ Simulation API
if you want to obtain a module whose name is "node", you do not need to manually check the name of every module - there is a useful method getModuleByPath() see OMNeT++ Simulation Manual
EDIT: thanks to Scheff and everyone else who commented
I am currently attempting to communicate with a serial device and have to change a foreach loop into a range based for loop. In order to do this I have written the following code:
std::vector<QSerialPortInfo> serialList;
for (QSerialPortInfo const &serialPortInfo : serialList)
{
qDebug() << "check/n";
if (serialPortInfo.hasVendorIdentifier () && serialPortInfo.hasProductIdentifier ())
{
if (serialPortInfo.vendorIdentifier () == trackerVendorID &&
serialPortInfo.productIdentifier () == trackerProductID)
{
trackerPortName = serialPortInfo.portName ();
trackerIsAvailable = true;
}
}
}
The problem is that this just generates an empty vector so the for loop is never used and the qDebug "check" is never called. I know I need to put something in with QSerialPortInfo::availablePorts() but I can't for the life of me work out how.
You write:
std::vector<QSerialPortInfo> serialList;
But QSerialPortInfo::availablePorts() does not return a std::vector, it returns a QList<QSerialPortInfo>, which you can use as is in the for loop:
QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo& serialPortInfo : serialList)
{
...
I'm writing several LLVM passes. One of them is a ModulePass that performs some analyzations but does not change anything (no functions, no metadata, no variables,...). It only looks at some metadata nodes and thats it.
MyModuleChecker.cpp:
INITIALIZE_PASS_BEGIN(MyModuleChecker, "mmc", "Check module", false, true)
INITIALIZE_PASS_END(MyModuleChecker, "mmc", "Check module", false, true)
char MyModuleChecker::ID = 0;
namespace llvm {
Pass* createMyModuleCheckerPass() {
return new MyModuleChecker();
}
}
MyModuleChecker::MyModuleChecker(void) : ModulePass(ID) {
initializeMyModuleCheckerPass(*PassRegistry::getPassRegistry());
}
void MyModuleChecker::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
bool MyModuleChecker::runOnModule(Module &M) {
// ...
return false; // <-- Under all circumstances
}
And then there is a second pass. That pass is a LoopPass and basiclly performs some loop unrolling tasks depending on some criteria. For computing the unroll count the pass needs the results of the MyModuleChecker pass. So I put it in the dependencies.
MyLoopUnroll.cpp:
INITIALIZE_PASS_BEGIN(MyLoopUnroll, "myloopunroll", "Unroll loops", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopInfo)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
INITIALIZE_PASS_DEPENDENCY(MyModuleChecker)
INITIALIZE_PASS_DEPENDENCY(DataLayoutPass)
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_END(MyLoopUnroll, "myloopunroll", "Unroll loops", false, false)
char MyLoopUnroll::ID = 0;
namespace llvm {
Pass* createMyLoopUnrollPass() {
return new MyLoopUnroll();
}
}
MyLoopUnroll::MyLoopUnroll()
: LoopPass(ID), MDK(nullptr), LI(nullptr), SE(nullptr), AC(nullptr),
DL(nullptr) {
initializeMyLoopUnrollPass(*PassRegistry::getPassRegistry());
}
void HDLLoopUnroll::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<LoopInfo>();
AU.addRequired<ScalarEvolution>();
AU.addRequired<MyModuleChecker>();
AU.addPreserved<MyModuleChecker>();
AU.addRequired<DataLayoutPass>();
AU.addPreserved<DataLayoutPass>();
AU.addRequired<AssumptionCacheTracker>();
}
bool MyLoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
LI = &getAnalysis<LoopInfo>();
SE = &getAnalysis<ScalarEvolution>();
MDK = &getAnalysis<MyModuleChecker>(); // <-- Seems not to work
DL = &getAnalysis<DataLayoutPass>().getDataLayout();
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(*L->getHeader()->getParent());
if ((LI == nullptr) || (SE == nullptr) || (DL == nullptr) || (MDK == nullptr) || (AC == nullptr)) {
return false;
}
bool Changed = handleLoop(L, LPM);
return Changed;
}
The loop unrolling itself was not implemented by myself but instead I am using the already existing functions that LLVM provides and that are also used by the loop unrolling that LLVM provides.
Currently those passes are part of the Scalar-library so I adopted the corresponding files (include /llvm/Transforms/Scalar.h, LinkAllPasses.h, ...) accordingly. So my passes are not linked dynamicly to opt.
Now I want to run the passes using opt (I'm using LLVM 3.6):
opt -stats -debug -debug-pass=Structure -mem2reg -loop-rotate -myloopunroll -simplifycfg
I now get an assertion error:
LoopRotation: rotating Loop at depth 1 containing: %for.cond<header><exiting>,%for.body,%for.inc<latch>
Inserted PHI: %i.01 = phi i32 [ 0, %entry ], [ %i.0, %for.cond ]
LoopRotation: into Loop at depth 1 containing: %for.body<header>,%for.inc<latch><exiting>
opt: ~/llvm-clang/source/include/llvm/PassAnalysisSupport.h:214: AnalysisType& llvm::Pass::getAnalysisID(llvm::AnalysisID) const [with AnalysisType = MyModuleChecker; llvm::AnalysisID = const void*]: Assertion `ResultPass && "getAnalysis*() called on an analysis that was not " "'required' by pass!"' failed.
// ...
#8 0x1685a99 MyModuleChecker& llvm::Pass::getAnalysisID<MyModuleChecker>(void const*) const ()
#9 0x16857f0 MyModuleChecker& llvm::Pass::getAnalysis<MyModuleChecker>() const ()
#10 0x16853cd MyLoopUnroll::runOnLoop(llvm::Loop*, llvm::LPPassManager&) ()
#11 0xd34aaa llvm::LPPassManager::runOnFunction(llvm::Function&) ()
// ...
And I don't know where that error comes and why it occures (any yes, everything compiles without errors and warnings). It looks like the loop rotation pass is executed normally and then pass manager gets stuck in the loop unroll pass when calling the getAnalysis<MyModuleChecker>; analysis results.
If I ommit the -simplifycfg and do not run the simplifycfg pass after my own loopunrolling pass everything works fine on the sameprogram and there is no assertion error. Afterwards the loop is unrolled.
It also seems as if the error does not occur if the ModuleChecker pass is transformed into a FunctionPass.
Could anyone tell my why this assertion error occures and (perhaps) how to solve that issue?
In the below code once I hit check_access as 0 how do I preserve the value and hit the
if condition below ($check_root && $check_access) . Break will only terminate the inner loop. But the other loops will continue as per me.
} else {
set check_access 0
break
}
}
}
if {$check_root && $check_access} {
set result 1
} else {
set result 0
}
The break and continue operations only go out one level of looping. If you need more than that, consider refactoring so that you can just return. Alternatively, try a custom exception in Tcl 8.6:
try {
foreach a $longList1 {
foreach b $longList2 {
if {[someCondition $a $b]} {
# Custom non-error exception
return -level 0 -code 123
}
}
}
} on 123 {} {
# Do nothing; we're out of the loop
}
break jumps to the end of the innermost loop only, and Tcl has no goto. But return, unless it's inside a catch or similar, exits a procedure which is like jumping to the end of it. So if you make the outermost loop the last command of the procedure (if your code is top-level, you have to put it in a procedure first to be able to use return), you can use return as a multi-break. Just move the commands after the loop out of the procedure and into the caller's code:
proc callMe {} {
foreach ... {
foreach ... {
if ... {
return
}
}
}
# move this code from here...
}
callMe
# ...to here
Another way is to put in extra tests:
set done 0
foreach ... {
foreach ... {
foreach ... {
if ... {
set done 1
break
}
}
if {$done} {break}
}
if {$done} {break}
}
I have this C++ program with the following general structure
1st while (condition A == true)
//some code for 1st loop
2nd while (condition B == true)
//some code for 2nd loop
try
//some code for try
catch
//condition B == false (supposed to leave 2nd loop and go back to first loop)
I want it to get out of 2nd loop when there's an exception and go back to 1st loop until condition B is tue again. As described above it doesn't work as I expect. What seems to be happening is that code gets stuck in catch and never leaves it.
How can I arrange it to make it work as I need?
Note: condition A is never false.
add the break keyword to the catch
Also notice that you have b == false;
That is checking that b is equal to false, not setting b = false.
bool flag1 = true, flag2 = true;
while (flag1)
{
// some work so that flag2 == true
while (flag2)
{
try
{
}
catch (...) // any exception happens
{
break;
}
}
}
1st while (condition A == true)
//some code for 1st loop
2nd while (condition B == true)
//some code for 2nd loop
try
//some code for try
catch
{
//condition B == false (supposed to leave 2nd loop and go back to first loop)
break ;
}
Notice: Please do not use, even in examples, things like condition A == true. It is better to use while (condition A).
You can call break within the catch block to escape the second loop:
void foo(void) {
bool A(true);
while (A) {
bool B(doSomething());
while (B) {
try {
B = doSomethingElseThatMayThrow();
} catch (...) {
break;
}
}
}
}
Alternatively, you could place the second loop inside the try block:
void foo(void) {
bool A(true);
while (A) {
bool B(doSomething());
try {
while (B) {
B = doSomethingElseThatMayThrow();
}
} catch (...) {}
}
}