gcc - leverage compiler to aid in code instrumentation - c++

BACKGROUND
I'm developing on OMAP 5 (ARM) and using a QNX gcc-based C++ compiler.
I know about the ability of gcc to insert a custom entry/exit callback for each function but I'd like to have more info than that.
PROBLEM
For starters, I want to instrument every control-flow statement
void func()
{
if(bob == 9)
{
bob = 55;
}
else
{
bob = 101;
}
}
Would become
void func()
{
if(bob == 5)
{
MACRO(0x1433) //0x1433 = ID for this particular if-statement
bob = 55;
}
else
{
MACRO(0x3243) //0x3243 = ID for this particular else-statement
bob = 99;
}
}
I know I could do the parsing myself but for more complex statements, it would get messy.
QUESTION
The gcc compiler already does the parsing of the code in the process of compilation.
Is there any way I can leverage some intermediate output so I can more easily identify control-flow statements?
Obviously there's the preprocessed output but that only resolves macros

Related

Simulating Leach has encounter a problem. Finished with error in omnet++

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

llvm pass to flatten (some) nested loops

I want to automatically rewrite simple nested loops as non nested ones.
For example, I have the following code:
if (y >= 0)
{
while (x>y)
{
x -= y+1;
for (z=y; z>0; z--) /* nothing */;
}
}
And I would like some llvm magic to happen so that it becomes:
if (y >= 0)
{
bool outer = true;
while (x>y)
{
if (outer) { z = y; }
if (z > 0) { z--; outer = false; }
else { x-= y+1; outer = true; }
}
}
Am I being over optimistic thinking such a pass exists?
I tried writing opt --help > /tmp/passes.txt && grep "loop" /tmp/passes.txt
but there are so many loop passes I don't know where to start.
This optimization is called loop fusion. I haven't tried your code but Polly should be able to fuse such loops. Polly is the polyhedral compiler framework that ships with LLVM but it should build with LLVM by default. If it does not then you'd need to pass -DLLVM_POLLY_BUILD:BOOL=ON to cmake to build polly with llvm.
Here's the documentation on how to invoke polly optimizations with clang/llvm.
https://polly.llvm.org/docs/UsingPollyWithClang.html#optimizing-with-polly

PhysFS_init() returns non-zero with error: "no error"

Im experiencing a rather weird crash in my code and im unsure as to what causes it. Im trying to use PhysFS in my c++ code. the code below is part of a class and Visual Studio 2017 tells me that the crash appears in PHYSFS_mount() and subsequently in EnterCriticalSection(), which to my understanding has something to do with mutexes. Now from my understanding this should be correct (Note that the main calls initArchives() first)
physfs_initialized = false;
...
void scope::parse_archive(const std::string& archive_path, const std::string& path_in_archive)
{
assert(physfs_initialized);
m_archivePath = archive_path;
m_relativeArchivePath = path_in_archive.substr(1);
//fsx = std::filesystem or std::expiremental::filesystem whatever floats your boat
if(exists(fsx::path(archive_path))) return;
if(!PHYSFS_mount(m_archivePath.c_str(),"",0)) return;
const auto file = PHYSFS_openRead(m_relativeArchivePath.c_str());
if(file) m_isValid = true;
PHYSFS_close(file);
PHYSFS_unmount(m_archivePath.c_str());
}
...
void initArchives(char ** argv)
{
if (!PHYSFS_init(argv[0])) physfs_initialized = true;
//a bit of ugly syntax because of the need to consume the return type
atexit([]() {PHYSFS_deinit(); });
}
The crash apparently appears here
int __PHYSFS_platformGrabMutex(void *mutex)
{
EnterCriticalSection((LPCRITICAL_SECTION) mutex); // <-- here
return 1;
} /* __PHYSFS_platformGrabMutex */
Am I doing something wrong here ? Is this a problem of the library or even with my OS ? Was there something in the buildstep of PhysFS that I missed ?
Edit: I noticed that I read the return value of PHYSFS_init() wrong, however now I'm even more confused as PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()) returns "no error", what is going on here ?
Apparently there is a bug in PhysFS regarding Windows 10. That prohibits the correct execution of PHYSFS_init()
changing line 578 of phsyfs_platform_windows.c to
rc = pGetDir(accessToken, NULL, &psize);
and a recompile of the library fixed the problem for me :/
https://hg.icculus.org/icculus/physfs/rev/ece6769c0676
https://discourse.libsdl.org/t/resolved-physfs-exception-thrown/25697/11

C++: both classes do not run concurrently

its my first time here. My code is suppose to make two ultrasonic sensors function at the same time using an mbed. However, i cant seem to make both classes void us_right() and void us_left() in the code run concurrently. Help please :(
#include "mbed.h"
DigitalOut triggerRight(p9);
DigitalIn echoRight(p10);
DigitalOut triggerLeft(p13);
DigitalIn echoLeft(p14);
//DigitalOut myled(LED1); //monitor trigger
//DigitalOut myled2(LED2); //monitor echo
PwmOut steering(p21);
PwmOut velocity(p22);
int distanceRight = 0, distanceLeft = 0;
int correctionRight = 0, correctionLeft = 0;
Timer sonarRight, sonarLeft;
float vo=0;
// Velocity expects -1 (reverse) to +1 (forward)
void Velocity(float v) {
v=v+1;
if (v>=0 && v<=2) {
if (vo>=1 && v<1) { //
velocity.pulsewidth(0.0014); // this is required to
wait(0.1); //
velocity.pulsewidth(0.0015); // move into reverse
wait(0.1); //
} //
velocity.pulsewidth(v/2000+0.001);
vo=v;
}
}
// Steering expects -1 (left) to +1 (right)
void Steering(float s) {
s=s+1;
if (s>=0 && s<=2) {
steering.pulsewidth(s/2000+0.001);
}
}
void us_right() {
sonarRight.reset();
sonarRight.start();
while (echoRight==2) {};
sonarRight.stop();
correctionRight = sonarLeft.read_us();
triggerRight = 1;
sonarRight.reset();
wait_us(10.0);
triggerRight = 0;
while (echoRight==0) {};
// myled2=echoRight;
sonarRight.start();
while (echoRight==1) {};
sonarRight.stop();
distanceRight = ((sonarRight.read_us()-correctionRight)/58.0);
printf("Distance from Right is: %d cm \n\r",distanceRight);
}
void us_left() {
sonarLeft.reset();
sonarLeft.start();
while (echoLeft==2) {};
sonarLeft.stop();
correctionLeft = sonarLeft.read_us();
triggerLeft = 1;
sonarLeft.reset();
wait_us(10.0);
triggerLeft = 0;
while (echoLeft==0) {};
// myled2=echoLeft;
sonarLeft.start();
while (echoLeft==1) {};
sonarLeft.stop();
distanceLeft = (sonarLeft.read_us()-correctionLeft)/58.0;
printf("Distance from Left is: %d cm \n\r",distanceLeft);
}
int main() {
while(true) {
us_right();
us_left();
}
if (distanceLeft < 10 || distanceRight < 10) {
if (distanceLeft < distanceRight) {
for(int i=0; i>-100; i--) { // Go left
Steering(i/100.0);
wait(0.1);
}
}
if (distanceLeft > distanceRight) {
for(int i=0; i>100; i++) { // Go Right
Steering(i/100.0);
wait(0.1);
}
}
}
wait(0.2);
}
You need to use some mechanism to create new threads or processes. Your implementation is sequential, there is nothing you do that tells the code to run concurrently.
You should take a look at some threads libraries (pthreads for example, or if you have access to c++11, there are thread functionality there) or how to create new processes as well as some kind of message passing interface between these processes.
Create two threads, one for each ultrasonic sensor:
void read_left_sensor() {
while (1) {
// do the reading
wait(0.5f);
}
}
int main() {
Thread left_thread;
left_thread.start(&read_left_sensor);
Thread right_thread;
right_thread.start(&read_right_sensor);
while (1) {
// put your control code for the vehicle here
wait(0.1f);
}
}
You can use global variables to write to when reading the sensor, and read them in your main loop. The memory is shared.
Your first problem is that you have placed code outside of your infinite while(true) loop. This later code will never run. But maybe you know this.
int main() {
while(true) {
us_right();
us_left();
} // <- Loops back to the start of while()
// You Never pass this point!!!
if (distanceLeft < 10 || distanceRight < 10) {
// Do stuff etc.
}
wait(0.2);
}
But, I think you are expecting us_right() and us_left() to happen at exactly the same time. You cannot do that in a sequential environment.
Jan Jongboom is correct in suggesting you could use Threads. This allows the 'OS' to designate time for each piece of code to run. But it is still not truly parallel. Each function (classes are a different thing) will get a chance to run. One will run, and when it is finished (or during a wait) another function will get its chance to run.
As you are using an mbed, I'd suggest that your project is an MBED OS 5 project
(you select this when you start a new project). Otherwise you'll need to use an RTOS library. There is a blinky example using threads that should sum it up well. Here is more info.
Threading can be dangerous for someone without experience. So stick to a simple implementation to start with. Make sure you understand what/why/how you are doing it.
Aside: From a hardware perspective, running ultrasonic sensors in parallel is actually not ideal. They both broadcast the same frequency, and can hear each other. Triggering them at the same time, they interfere with each other.
Imagine two people shouting words in a closed room. If they take turns, it will be obvious what they are saying. If they both shout at the same time, it will be very hard!
So actually, not being able to run in parallel is probably a good thing.

result of call warning - want to use the result?

I have some difficulties with the new Swift 3.0. First I know the “result of call is unused” warning has been debated a few times already. I have read the topics in question and usually the suggested answer is to use #discardableResult or using _ = before the function. But in my case this isn’t working. Before upgrading xCode the code worked great. I tested it on my iPad and everything was ok. But then once I upgraded xCode and had to convert the code to comply with Swift 3.0 the problem appeared.
The thing is that whatever I do, the object in the game isn’t showing as it should. Like I said, previously it worked, but now it doesn’t anymore. When the character runs into the object and it crashes it, the game should display a crashed object, but instead it shows an image with a red “X” as if the image isn’t there.
Here is the code. I would appreciate any suggestion you guys have. Thanks in advance
for block in Blocks
{
block.move()
block.isColB()
if(block.manager.HasFloorL2)
{
if(block.isOnL2())
{
if(block.manager.FloorL2Obstact)
{
block.ObsColL2() // here, result of call to ObscColL2() is unused
}
break;
}
}
if(block.manager.HasFloorL1)
{
if(block.isOnL1())
{
if(block.manager.FloorL1Obstact)
{
block.ObsColL1() // here, result of call to ObscColL1() is unused
}
break;
}
}
}
Here is the function it refers to.
func ObsColL1() -> Bool
{
if(kong.Node.position.x+kong.Node.size.width*0.7 > self.holder.position.x+ObstacleL1.Node.position.x
&& kong.Node.position.x+kong.Node.size.width*0.7 < self.holder.position.x+ObstacleL1.Node.position.x+ObstacleL1.Node.size.width*0.3)
{
if(kong.Y() <= self.holder.position.y+(ObstacleL1.Node.position.y)+ObstacleL1.Node.size.height*0.7 && kong.Y() >= self.holder.position.y+ObstacleL1.Node.position.y)
{
if(kong.state != heroStates.flash && !self.ObstacleL1.crashed)
{
kong.Node.position.x = self.holder.position.x+ObstacleL1.Node.position.x-(kong.Node.size.width*0.55)
kong.Node.run(SKAction.moveTo(y: self.holder.position.y+ObstacleL1.Node.position.y+ObstacleL1.Node.size.height/2, duration: 0.5))
kong.die()
}
else
{
ObstacleL1.crash()
return true
}
}
}
return false
}
EDIT:
before and after
before and after
before and after 2