Creating custom gcc attribute to instrument specific functions: whitelisting, not blacklisting - gcc

I'm using gcc's -finstrument-functions option. To minimize the overhead, I want to instrument only a few functions. However, gcc only lets you blacklist functions (with the no_instrument_function attribute, or by providing a list of paths). It doesn't let you whitelist functions.
So I wrote a small gcc plugin adding an instrument_function attribute. This lets me set the instrumentation "flag" for a specific function (or, rather, clear the no instrumentation flag):
tree handle_instrument_function_attribute(
tree * node,
tree name,
tree args,
int flags,
bool * no_add_attrs)
{
tree decl = *node;
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(decl) = 0;
return NULL_TREE;
}
However, from my understanding, this does not work. Looking at the gcc source, for this flag to actually do anything, you need to also use -finstrument-functions. See gcc/gimplify.c:14436:
...
/* If we're instrumenting function entry/exit, then prepend the call to
the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
catch the exit hook. */
/* ??? Add some way to ignore exceptions for this TFE. */
if (flag_instrument_function_entry_exit
&& !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl)
/* Do not instrument extern inline functions. */
&& !(DECL_DECLARED_INLINE_P (fndecl)
&& DECL_EXTERNAL (fndecl)
&& DECL_DISREGARD_INLINE_LIMITS (fndecl))
&& !flag_instrument_functions_exclude_p (fndecl))
...
It first checks that the global -finstrument-functions flag is enabled. Then it checks a specific function's flag, which, from what I understand, is enabled by default. So all other functions that don't have my instrument_function attribute would still be instrumented.
Is there a way to clear this flag for all functions first, then handle my instrument_function attribute to set the flag for those functions only?

The trick was only defining the attribute, but not actually using any handling function, and do the processing elsewhere.
We still use -finstrument-functions to enable instrumentation for all functions at first. We can register a callback for PLUGIN_FINISH_PARSE_FUNCTION, which checks everything. For every function declaration, it checks its attributes. If it has the instrument_function attribute, it sets the flag for the instrumentation to be added later as usual. If the function doesn't have the attribute, it clears the flag.
#include <stdio.h>
#include "gcc-plugin.h"
#include "plugin-version.h"
#include "tree.h"
int plugin_is_GPL_compatible;
static struct plugin_info info = {
"0.0.1",
"This plugin provides the instrument_function attribute.",
};
static struct attribute_spec instrument_function_attr =
{
"instrument_function",
0,
-1,
false,
false,
false,
NULL, // No need for a handling function
};
static void register_attributes(void * event_data, void * data)
{
register_attribute(&instrument_function_attr);
}
void handle(void * event_data, void * data)
{
tree fndecl = (tree) event_data;
// Make sure it's a function
if (TREE_CODE(fndecl) == FUNCTION_DECL)
{
// If the function has our attribute, enable instrumentation,
// otherwise explicitly disable it
if (lookup_attribute("instrument_function", DECL_ATTRIBUTES(fndecl)) != NULL_TREE)
{
printf("instrument_function: (%s:%d) %s\n",
DECL_SOURCE_FILE(fndecl),
DECL_SOURCE_LINE(fndecl),
get_name(fndecl));
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(fndecl) = 0;
}
else
{
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(fndecl) = 1;
}
}
}
int plugin_init(
struct plugin_name_args * plugin_info,
struct plugin_gcc_version * version)
{
register_callback(
plugin_info->base_name,
PLUGIN_INFO,
NULL,
&info);
register_callback(
plugin_info->base_name,
PLUGIN_FINISH_PARSE_FUNCTION,
handle,
NULL);
register_callback(
plugin_info->base_name,
PLUGIN_ATTRIBUTES,
register_attributes,
NULL);
return 0;
}

Related

wxTimer not calling overriden Notify()

I'm running into an issue where I implemented a derived wxTimer class to override the Notify() call since I'm not using an owner implementation as described in the documentation.
When I debug the run, I can see
the timer is being instantiated
my_timer_instance->IsRunning() returns true
MyTimer::Notify() is never called
This leads me to believe that the timer is being set and running, but when it expires it's calling the base class Notify() procedure and not my override it's not calling notify() but I'm not sure why.
EDIT: I added frame->getTimer()->Notify(); to my app and the correct procedure was called. Therefore, the timer just isn't calling Notify when it expires.
EDIT2: Added this minimal working example, and the timer works as expected. I'll try to compare the two and see what the problem is.
MyApp.hpp
#pragma once
#ifndef __NONAME_H__
#define __NONAME_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/statusbr.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/frame.h>
#include <wx/timer.h>
///////////////////////////////////////////////////////////////////////////
class MyTimerClass : public wxTimer
{
wxFrame* MyFrame;
public:
MyTimerClass(wxFrame* frame): MyFrame(frame) {};
void Notify() override;
};
///////////////////////////////////////////////////////////////////////////////
/// Class MyFrame1
///////////////////////////////////////////////////////////////////////////////
class MyFrame1 : public wxFrame
{
private:
protected:
wxStatusBar* m_statusBar1;
MyTimerClass* MyTimer;
public:
void StartTimer(int TimeInSeconds);
MyFrame1(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxEmptyString, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(500, 300), long style = wxDEFAULT_FRAME_STYLE | wxTAB_TRAVERSAL);
~MyFrame1();
};
#endif //__NONAME_H__
MyApp.cpp
#include "MyApp.hpp"
#include "wx/wxprec.h"
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
///////////////////////////////////////////////////////////////////////////
void MyTimerClass::Notify()
{
MyFrame->SetStatusText("Timer popped", 0);
}
MyFrame1::MyFrame1(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style)
{
MyTimer = new MyTimerClass(this);
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
m_statusBar1 = this->CreateStatusBar(1, wxSTB_SIZEGRIP, wxID_ANY);
this->Centre(wxBOTH);
this->StartTimer(5);
}
void MyFrame1::StartTimer(int TimeInSeconds)
{
SetStatusText("Timer started with " + std::to_string(TimeInSeconds) + " seconds.");
MyTimer->Start(TimeInSeconds * 1000);
}
MyFrame1::~MyFrame1()
{
}
// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------
// the application icon (under Windows it is in resources and even
// though we could still include the XPM here it would be unused)
#ifndef wxHAS_IMAGES_IN_RESOURCES
#include "../sample.xpm"
#endif
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
class MyApp : public wxApp
{
public:
virtual bool OnInit() wxOVERRIDE;
};
enum
{
// menu items
Minimal_Quit = wxID_EXIT,
Minimal_About = wxID_ABOUT
};
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
// call the base class initialization method, currently it only parses a
// few common command-line options but it could be do more in the future
if (!wxApp::OnInit())
return false;
// create the main application window
MyFrame1 *frame = new MyFrame1(NULL, -1, "Test Frame");
frame->Show(true);
return true;
}
#BobbyTables,
From the documentation:
This member should be overridden by the user if the default
constructor was used and SetOwner() wasn't called.
Is it the case?
Nothing seems to be wrong in the code you show (although I'd change a few things, such as using raw pointer for my_timer_instance), so the problem must be elsewhere. As usual, the best would be to come up with a SSCCE, without it I can only offer some guesses as to what the problem actually is.
Are you running the event loop? The timers will only fire when it's running, so if you block doing some computation, this wouldn't happen.
Also, what is frame in Notify()? Is this a global (I'd rather pass it as parameter to MyTimer ctor)?
So after mimicking the code provided in the question, the following changes were made:
Instead of using a getter and setter to access the private timer member, I instead use
void refreshTimer(int time_in_seconds) in my parent frame class and create the timer in the parent frame's constructor rather than letting the app create it and pass it in.
I don't see why either of those two things would change the behavior of the timer but the timer now works as expected. I apologize for not being able to identify a concrete bug as the source of the problem.
NOTE: This behavior was caused by the timer being invoked outside the wxwindow's thread. Be careful when creating multithreaded programs using wxwidgets as a GUI. To circumvent this issue since I needed the timer to be invoked in a different thread, I created my own timer class that works correctly.

Error when compiling ncurses

I'm trying to compile ncurses 5.9 for an embedded system (using buildroot) and I get this error message:
In file included from ../c++/cursesm.h:39:0,
from ../c++/cursesm.cc:35:
../c++/cursesp.h: In member function ‘T* NCursesUserPanel<T>::UserData() const’:
../c++/cursesp.h:256:43: error: no matching function for call to
‘NCursesUserPanel<T>::get_user() const’
return reinterpret_cast<T*>(get_user ());
Here's the code in question:
/* We use templates to provide a typesafe mechanism to associate
* user data with a panel. A NCursesUserPanel<T> is a panel
* associated with some user data of type T.
*/
template<class T> class NCursesUserPanel : public NCursesPanel
{
public:
NCursesUserPanel (int nlines,
int ncols,
int begin_y = 0,
int begin_x = 0,
const T* p_UserData = STATIC_CAST(T*)(0))
: NCursesPanel (nlines, ncols, begin_y, begin_x)
{
if (p)
set_user (const_cast<void *>(p_UserData));
};
// This creates an user panel of the requested size with associated
// user data pointed to by p_UserData.
NCursesUserPanel(const T* p_UserData = STATIC_CAST(T*)(0)) : NCursesPanel()
{
if (p)
set_user(const_cast<void *>(p_UserData));
};
// This creates an user panel associated with the ::stdscr and user data
// pointed to by p_UserData.
virtual ~NCursesUserPanel() {};
T* UserData (void) const
{
return reinterpret_cast<T*>(get_user ());
};
// Retrieve the user data associated with the panel.
virtual void setUserData (const T* p_UserData)
{
if (p)
set_user (const_cast<void *>(p_UserData));
}
// Associate the user panel with the user data pointed to by p_UserData.
};
Line 256 is this one: return reinterpret_cast<T*>(get_user ());
The problem here was due to a compiler update to g++ (Debian 7.2.0-5). New compilers have better error handling, and this old code was written without its benefit. The solution here is to either use a more recent version of ncurses (no-go for my particular situation) or use an older compiler. Since my host system is Debian, I used update-alternatives to switch to g++ 6.4 and the problematic error message went away.
I'm leaving this here because Google gave me no good results for the error message.

ABI-compatible shared_ptr implementation

I am working on a COM-style complier cross-compatible plugin framework relying on compatible virtual table implementations for ABI compatibility.
I define interfaces containing only pure virtual member functions and an overridden delete operator to channel destruction to the place of implementation.
This works well with extern "C" factory functions instantiating the plugin implementation of the interface and returning an interface-type pointer.
However, I was wondering if smart pointers wouldn't be a more modern way to manage the lifetime of the plugin object. I think I have actually managed to
create a standard-layout shared_ptr/weak_ptr that uses a reference count object defined and implemented the same way as the plugin interfaces.
It looks something like this:
class IRefCount
{
public:
virtual void incRef() = 0;
virtual void decRef() = 0;
virtual bool incRefIfNZ() = 0;
virtual void incWRef() = 0;
virtual void decWRef() = 0;
virtual long uses() const = 0;
protected:
~ref_count_base() = default; //prohibit automatic storage
}
template <typename Ty>
class shared_ptr
{
private:
Ty* ptr_;
IRefCount* ref_count_;
public:
//member functions as defined by C++11 spec
}
Three questions:
Before the smart pointer the factory function looked like this:
extern "C" IPlugin* factory() { try { return new Plugin(); } catch (...) { return nullptr; } }
Now, it looks like this:
extern "C" shared_ptr<IPlugin> factory() { try { return shared_ptr<IPlugin>(new Plugin()); } catch (...) { return nullptr; } }
VS2013 is giving me warning C4190: 'factory' has C-linkage specified, but returns UDT 'shared_ptr' which is incompatible with C. According to MSDN this is OK, provided that both caller and callee are C++.
Are there any other potential issues with returning standard-layout objects from "C" linkage functions?
Calling conventions. Should I be specifying __stdcall for all pure-virtual interface functions and factory functions?
I am using <atomic> for the reference count. I am writing platform-independent code and I have not yet tried compiling for ARM. According to http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/ch01s02s01.html armcc does not implement std::atomic. Any better compilers/stl out there?

boost asio and libcurl mutiple handler

im learning libcurl and boost:asio from this nice post http://www.lijoantony.com/?p=76
though i do have one question about the source code at:
sample code
the main function looks like:
int main(int argc, char **argv)
{
GlobalInfo g;
CURLMcode rc;
(void)argc;
(void)argv;
memset(&g, 0, sizeof(GlobalInfo));
g.multi = curl_multi_init();
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
new_conn((char *)"http://us.download.nvidia.com/XFree86/Linux-x86_64/331.79/NVIDIA-Linux-x86_64-331.79.run", &g); /* add a URL */
/* enter io_service run loop */
io_service.run();
curl_multi_cleanup(g.multi);
fprintf(MSG_OUT, "\ndone.\n");
return 0;
}
i see there is no place calling the curl function curl_multi_perform()
how does the tasks get started at the very begining?
I see there is no place calling the curl function curl_multi_perform()
This is because this sample code uses an alternative API called curl_multi_socket_action:
curl_multi_socket_action is then used instead of curl_multi_perform.
(see the MULTI_SOCKET section of the official documentation for more details)
how does the tasks get started at the very begining?
The magic occurs thanks to the CURLMOPT_TIMERFUNCTION option, curl_multi_add_handle function and corresponding timer logic.
If you refer to the static void new_conn(char *url, GlobalInfo *g ) function you can see that:
static void new_conn(char *url, GlobalInfo *g )
{
/* ... */
rc = curl_multi_add_handle(g->multi, conn->easy);
mcode_or_die("new_conn: curl_multi_add_handle", rc);
/* note that the add_handle() will set a time-out to trigger very soon so
that the necessary socket_action() call will be called by this app */
}
So in practice everything starts by calling new_conn(...) which in turn will trigger multi_timer_cb which then calls timer_cb.
And timer_cb performs the curl_multi_socket_action.

Does GCC LTO perform cross-file dead code elimination?

Say I have a function
void do_something() {
//....
#ifdef FEATURE_X
feature_x();
#endif
//....
}
I can compile and run this with no problems; if I want the feature I can pass -D FEATURE_X and it works.
However, what if I would like to put do_something into another file (And not have to recompile that file as well each time I decide to change the option). If it was in the same file, I assume that
const int FEATURE_X=0;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
will use dead code elimination properly, eliminating the call. If I put this in another file, without LTO,
extern const int FEATURE_X;
void do_something() {
//....
if(FEATURE_X) {
feature_x();
}
//....
}
It will not remove the code (It has no way of knowing). So, with link time optimization enabled, can the compiler detect the value of FEATURE_X at link time, determine if the code is used or not, and remove it if appropriate?
GCC does cross module unreachable function removal, but it will not be able to determine the code is dead in your last testcase, because the constant value of FEATURE_X will be determined too late.
If you will use -D way or put your const int FEATURE_X=0; into every module then yes, the code will be eliminated.

Resources