2

I have a scenario, where I need to wrap few functions in C language. Basically , I need to add few information before the function , so that we know when it is called and other debugging and async flow information.

I 'm able to wrap sync calls with wrap option mentioned Override a function call in C

But, is there a way to wrap the callbacks in GCC or LD or sharedlibraries , which is being passed to function.

One option which I have in mind, is to store the callback and override it with another function.

Is there any other solution without storing and manipulation to do it more efficiently?

Community
  • 1
  • 1
yathish
  • 17
  • 2

1 Answers1

1

You can do the same thing as the article you linked. To wrap malloc:

// wrap.h
#define malloc(N) wrapped_malloc(N)

void *wrapped_malloc(size_t n);

// wrap.c
#include "wrap.h"
#undef malloc 

void *wrapped_malloc(size_t n) {
  printf("called malloc\n"); 
  return malloc(n);
}

// mycode.c
#include "wrap.h"
...
void *p = malloc(42);
...

Prints "called malloc" when it executes.

Or maybe I'm misunderstanding your question. If so, give an example.

Addition

Contrary to your use of terms, there is no inherent connection between callbacks and asynchronous execution. For example, libpng makes excellent use of callbacks.

But since you are probably interested in thread management calls, let's wrap:

int pthread_create(pthread_t *thread,
    const pthread_attr_t *attr,
    void *(*start_routine)(void*), void *arg);

For this we define:

// wrap.h
#define pthread_create(Thread, Attr, StartRoutine, Arg) \
    wrapped_pthread_create(Thread, Attr, StartRoutine, Arg)

int wrapped_pthread_create(pthread_t *thread,
    const pthread_attr_t *attr,
    void *(*start_routine)(void*), void *arg);

Then:

// wrap.c
#include "wrap.h"
#undef pthread_create 

// __thread is gcc's thread local storage class keyword.
// If you're using a different compiler, adjust accordingly.
static __thread void *(*captured_start_routine)(void*);

static void *wrapped_start_routine(void *arg) {
  printf("called start routine\n");
  return captured_start_routine(arg);
}

int wrapped_pthread_create(pthread_t *thread,
    const pthread_attr_t *attr,
    void *(*start_routine)(void*), void *arg) {
  captured_start_routine = start_routine;
  printf("called pthread_create\n");
  return pthread_create(thread, attr, wrapped_start_routine, arg);
}
Gene
  • 46,253
  • 4
  • 58
  • 96
  • Many Thanks for the support.suppose my public interface to library is : API_Interface(int size, int (*fn) (int)); Now, if I have to wrap the callback which is being passed , how to do. For synchronous APi, like malloc whatever that is posted works, only think is for Async registerration of the API, if I have to know when the CB is called and I have to print some information of params how to do it, I don't know how. If you have any information let me know , how to do. Thanks – yathish Aug 18 '15 at 03:02
  • @yathish see new addition – Gene Aug 18 '15 at 03:39
  • Many Thanks for the info -Gene, will try and get back, – yathish Aug 18 '15 at 03:53