How to use LLVM's SanitizerCoverage code coverage instrumentation with a shared library? - clang

I have a shared library linked to an executable for which I would like to have code coverage instrumentation using custom _sanitizer_cov_trace_pc* functions.
library.cc
#include <stdio.h>
void so_function() {
printf("SO function.");
}
callbacks.cc
#include <stdint.h>
#include <stdio.h>
#include <sanitizer/coverage_interface.h>
extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
uint32_t *stop) {
static uint64_t N;
if (start == stop || *start) return;
printf("INIT: %p %p\n", start, stop);
for (uint32_t *x = start; x < stop; x++)
*x = ++N;
}
extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
if (!*guard) return;
void *PC = __builtin_return_address(0);
char PcDescr[1024];
__sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr));
printf("guard: %p %x PC %s\n", guard, *guard, PcDescr);
}
main.cc
#include <stdio.h>
void so_function();
int main(int argc, char **argv) {
so_function();
}
I compiled the library using clang's -fsanitize-coverage=trace-pc-guard into position-independent code (-fPIC) and then I created the shared library using both the resulted object file and callbacks.cc using -fsanitize=address.
I compiled main.cc and linked it with the shared library but it seems like these 2 custom __sanitizer_cov_trace_pc_guard* functions don't get called.
I would like have code coverage instrumentation using these 2 functions only for the shared library, and not for the main executable.

Related

Usage of FunctionPass over ModulePass when creating LLVM passes

I've seen quite a numerous amount of examples that go over creating functions passes (e.g. Brandon Holt and Adrian Sampson), but I am curious as to the difficulty in creating a module pass to do these very similar problems. I've tried to implement a module pass to display the global variable names using this example and llvm source code to understand how you have to iterate through members.
I am using a source compiled version of LLVM, and using the example from the above links to add the pass, and then running:
$ clang -Xclang -load -Xclang build/Skeleton/libSkeletonPass.so something.c
Which then returns this gibberish. However, if I implement a functionPass and just use Auto to determine the type to be initialized it's very straight forward and works. Am I just going about printing the global variables the wrong way?
This is a pastebin of the error output from the terminal. link
Skeleton.cpp
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/IR/LLVMContext.h"
using namespace llvm;
namespace {
// Helper method for converting the name of a LLVM type to a string
static std::string LLVMTypeAsString(const Type *T) {
std::string TypeName;
raw_string_ostream N(TypeName);
T->print(N);
return N.str();
}
struct SkeletonPass : public ModulePass {
static char ID;
SkeletonPass() : ModulePass(ID) {}
virtual bool runOnModule(Module &M) {
for (Module::const_global_iterator GI = M.global_begin(),
GE = M.global_end(); GI != GE; ++GI) {
errs() << "Found global named: " << GI->getName()
<< "\tType: " << LLVMTypeAsString(GI->getType()) << "!\n";
}
return false;
}
};
}
char SkeletonPass::ID = 0;
// Automatically enable the pass.
// http://adriansampson.net/blog/clangpass.html
static void registerSkeletonPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
PM.add(new SkeletonPass());
}
static RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
registerSkeletonPass);
something.c
int value0 = 5;
int main(int argc, char const *argv[])
{
int value = 4;
value += 1;
return 0;
}
I was able to figure this out after some extensive github searching. Here is the answer from which I was following a tutorial to help others who may be curious how to implement a Module Pass.

Any alternative solution for QMessagebox for IOS development (QWidget application only)?

I am using Qt 5.3 and trying to develop application for IOS.
Problem is, QWidget application in a iPhone Retina simulator:
QMessage becomes full-screen.
In Application output panel I see: This plugin does not support
propagateSizeHints().
So looking for alternative solution for QMessageBox. I don't want to learn QML yet.
If you do an overlay on top of your widget you can make something similar to the iOS popups.
Basically you create another widget, and you parent it to the widget you want it to be drawn on top of.
Here are some helpful flags and lines of code to put in your overlay constructor:
setPalette(Qt::transparent);
// if you have buttons on this overlay you probably don't want this one
setAttribute(Qt::WA_TransparentForMouseEvents);
QGraphicsDropShadowEffect * dse = new QGraphicsDropShadowEffect();
dse->setBlurRadius(20);
this->setGraphicsEffect(dse);
Then be sure to command a resize of your overlay when the parent widget resizes:
void ParentWidget::resizeEvent(QResizeEvent *event)
{
overlay->resize(event->size());
event->accept();
}
http://www.qtcentre.org/wiki/index.php?title=Widget_Overlay
UPDATE: Awesome example
main.cpp
#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
w.resize(300,600);
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "overlaydialogbox.h"
#include <QResizeEvent>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void resizeEvent(QResizeEvent *event);
private:
OverlayDialogBox * m_overlay;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_overlay = new OverlayDialogBox(this);
}
MainWindow::~MainWindow() { }
void MainWindow::resizeEvent(QResizeEvent *event)
{
m_overlay->resize(event->size());
event->accept();
}
overlaydialogbox.h
#ifndef OVERLAYDIALOGBOX_H
#define OVERLAYDIALOGBOX_H
#include <QWidget>
class OverlayDialogBox : public QWidget
{
Q_OBJECT
public:
explicit OverlayDialogBox(QWidget *parent = 0);
signals:
void accepted();
void rejected();
void finished(int);
public slots:
};
#endif // OVERLAYDIALOGBOX_H
overlaydialogbox.cpp
#include "overlaydialogbox.h"
#include <QGridLayout>
#include <QGraphicsEffect>
#include <QLabel>
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QIcon>
OverlayDialogBox::OverlayDialogBox(QWidget *parent) :
QWidget(parent)
{
setPalette(Qt::transparent);
// if you have buttons on this overlay you probably don't want this one
// setAttribute(Qt::WA_TransparentForMouseEvents);
QGraphicsDropShadowEffect * dse = new QGraphicsDropShadowEffect();
dse->setBlurRadius(20);
this->setGraphicsEffect(dse);
QGridLayout * grid = new QGridLayout();
this->setLayout(grid);
QMessageBox * msg = new QMessageBox(QMessageBox::Warning,"Testing","This is a test QMessageBox.");
QObject::connect(msg, SIGNAL(accepted()), this, SIGNAL(accepted()));
QObject::connect(msg, SIGNAL(finished(int)), this, SIGNAL(finished(int)));
QObject::connect(msg, SIGNAL(rejected()), this, SIGNAL(rejected()));
QObject::connect(msg, SIGNAL(finished(int)), this, SLOT(close()));
msg->setPalette(Qt::white);
grid->addWidget(msg);
}
Hope that helps.

Using C header and implementation files in Xcode iOS project

I'm trying to use a separate C header and implementation file in Xcode iOS/Objective-C project.
I want to use the method I implemented in main.m but I get these errors:
Full size here
I've included user.h in main.m
Note that Target Membership is selected in user.c for HelloWorld. When I deselect this the errors are gone. But when I try to run the app, I get these errors at compile time:
Full size here
When I implement the struct and method in main.m it compiles and runs just fine. But I don't get it why I can't use this particular code in a separate file?
Source Code:
user.h
#ifndef HelloWorld_user_h
#define HelloWorld_user_h
typedef struct {
char *name;
int age;
char sex;
} User; //sizeof(User) = 16 bytes
void CreateAndDisplay(User *usr, char *name, int age, char sex);
#endif
user.c
#include <stdio.h>
#include <stdlib.h>
void CreateAndDisplay(User *usr, char *name, int age, char sex) {
usr->name = name;
usr->age = age;
usr->sex = sex;
printf("User address -> value:\n");
printf("Name:\t%u\t->\t%s\n", (uint)usr, *&usr->name);
printf("Age:\t%u\t->\t%i\n", (uint)&usr->age, *&usr->age);
printf("Sex:\t%u\t->\t%c\n\n", (uint)&usr->sex, *&usr->sex);
printf("User has a size of %li bytes in memory", sizeof(*usr));
}
main.m
#import <UIKit/UIKit.h>
#import "HelloWorldAppDelegate.h"
#include <stdio.h>
#include <stdlib.h>
#include "user.h"
int main(int argc, char *argv[])
{
User user1;
CreateAndDisplay(&user1, "John Doe", 24, 'm');
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([HelloWorldAppDelegate class]));
}
}
These errors are because there are two types referenced in user.c that haven't been declared in headers that it imports: User (defined in user.h) and uint (defined in <sys/types.h>). To resolve these errors, inside user.c you should add the following includes:
#include "user.h"
#include <sys/types.h>
Try to include user.h in user.c, like you include stdio.h.

Lua does not load libs

I decided to add scripting with Lua. I've downloaded and compiled interpreter. It works fine, but when I want to use any functions from os.* or string.* libs, it says, that "attemt to index global 'os' (a nil value)"
Here is my code and should work, but it does not:
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
extern "C" {
#include "..\liblua\lua.h"
#include "..\liblua\lualib.h"
#include "..\liblua\lauxlib.h"
}
int main(int argc, TCHAR* argv[])
{
lua_State *LuaVM = luaL_newstate();
lua_pushcfunction(LuaVM,luaopen_base);
lua_call(LuaVM,0,0);
lua_pushcfunction(LuaVM,luaopen_math);
lua_call(LuaVM,0,0);
lua_pushcfunction(LuaVM,luaopen_string);
lua_call(LuaVM,0,0);
lua_pushcfunction(LuaVM,luaopen_table);
lua_call(LuaVM,0,0);
int error;
lua_pushstring(LuaVM,"Ver 0.525.5");
lua_setglobal(LuaVM,"Version");
while (true)
{
string strCode;
getline(cin,strCode);
error = luaL_loadbuffer(LuaVM,strCode.c_str(),strCode.length(),"") ||
lua_pcall(LuaVM,0,0,0);
if (error)
{
cout<< lua_tostring(LuaVM,-1)<<endl;
lua_pop(LuaVM,1);
}
}
lua_close(LuaVM);
return 0;
}
What's wrong with it?
In Lua 5.2 the standard luaopen_* functions do not set the corresponding global variables.
Why not copy and adapt the code in linit.c or just call luaL_openlibs?
Otherwise, do what they do: call luaL_requiref for each luaopen_* function.
See http://www.lua.org/source/5.2/linit.c.html#luaL_openlibs.

Open CV won't compile

I'm trying to compile some opencv code, but it is failing. I'm pretty sure I have the libraries included but it still has undefined references to the functions.
I'm running this command:
gcc -lhighgui -lcvaux -lcxcore -I /usr/local/include/opencv/ -L /usr/local/lib/ -o hello_world hello_world.c
and get this result
foo.cpp:(.text._ZN3Foo3barEv[Foo::bar()]+0x1f): undefined reference to `cvLoadImage'
foo.cpp:(.text._ZN3Foo3barEv[Foo::bar()]+0x2d): undefined reference to `cvWaitKey'
with this code:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"
class Foo{
public:
void bar(){
IplImage* img = 0;
img=cvLoadImage("C:/.../Pictures/image.jpg");
cvWaitKey(0);
system("PAUSE");
}
};
extern "C" {
Foo* Foo_new(){ return new Foo(); }
void Foo_bar(Foo* foo){ foo->bar(); }
}

Resources