I am using LD_PRELOAD to hook a library function, and in Linux it works perfectly. But I cannot figure out how to do the equivalent in OSX.
The setup I have on Linux is as follows:
The code is:
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
#include <ruby.h>
void
rb_raise(unsigned long exc, const char *fmt, ...)
{
static void (*libruby_rb_raise)
(unsigned long exc, const char *fmt, ...) = NULL;
void * handle;
char * error;
if (!libruby_rb_raise) {
handle = dlopen("/path/to/libruby.so",
RTLD_LAZY);
if (!handle) {
fputs(dlerror(), stderr);
exit(1);
}
libruby_rb_raise = dlsym(handle, "rb_raise");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(1);
}
}
// ...code...
return Qnil;
}
Which I then compile with:
gcc -Wall -O2 -fpic -shared -ldl -g -I/path/to/includes/ -o raise_shim.so raise_shim.c
I then execute with:
LD_PRELOAD=./raise_shim.so ruby
All of the above works well on Linux, what is the equivalent for each step to get this working on OSX? I have googled this and have not been able to get it to work with the information provided as the info for some of the steps are missing.
Thanks in advance!
Take a look at DYLD_INSERT_LIBRARIES. That's the variable you're looking for.
See also this answer.
Related
I am trying to make a C-program with multiple c-files in GTK3.
As models I am using:
how-to-split-a-c-program-into-multiple-files
and this
example-0.c
My program looks like this:
Functions.c (with the function activate)
#include "Functions.h"
#include <gtk/gtk.h>
#include "stdio.h"
static void activate (GtkApplication* app, gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
gtk_widget_show_all (window);
}
Function.h (the header file)
#include <gtk/gtk.h>
#ifndef FUNCTIONS_H_INCLUDED
#define FUNCTIONS_H_INCLUDED
static void activate (GtkApplication* app, gpointer user_data);
#endif
Main.c
#include "stdio.h"
#include <gtk/gtk.h>
#include "Functions.h"
int main(int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}
When I compile, is says:
gcc -Wall `pkg-config --cflags gtk+-3.0` Functions.c Main.c `pkg-config --libs gtk+-3.0`
Functions.c:7:13: warning: ‘activate’ defined but not used [-Wunused-function]
static void activate (GtkApplication* app, gpointer user_data)
^
In file included from Main.c:4:0:
Functions.h:7:14: warning: ‘activate’ used but never defined
static void activate (GtkApplication* app, gpointer user_data);
^
/tmp/ccWzazr0.o: I funktionen "main":
Main.c:(.text+0x38): undefined reference to `activate'
collect2: error: ld returned 1 exit status
and is not compiled!
Yes, GTK programs can be split into multiple C files.
You get an error because you are telling your compiler that the function is only visible within that single C source file:
static void activate (GtkApplication* app, gpointer user_data)
If you want to use that function from another source file, you need to remove static keyword.
Both in the header file as well in the C file you need to remove it.
My gcc version is 4.8.5
posix gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
I have two cpp files:
1.cpp and 2.cpp
while there is a static function in 1.cpp called by 2.cpp。
In most machine,we should like this:
g++ 2.cpp 1.cpp
or it will cause compile error or runtime error。
However,in my machine with gcc 4.8.5,I must compile using “g++ 1.cpp 2.cpp” to make it run successful。
Is this the property of gcc4.8.5? or there is something wrong on my soft,or I used it wrong?
==============================================================
My machine is centos7 installed on virtulbox of mac. Here is my code:
1.h
#include <map>
using namespace std;
class A {
private:
A();
static A _instance;
map<int, int> test_map;
public:
static A& get_instance();
static void fun();
};
1.cpp
#include <iostream>
#include "1.h"
using namespace std;
A A::_instance;
A::A() {
cout << "A::A()\n";
}
A& A::get_instance() {
cout << "A::get_instance()\n";
return A::_instance;
// static A instance;
// return instance;
}
void A::fun() {
cout << "A::fun()\n";
get_instance().test_map[1];
}
main.cpp
#include <iostream>
#include "1.h"
using namespace std;
int test() {
cout << "test()\n";
A::fun();
return 0;
}
int y = test();
int main() {
cout << "main()\n";
A::fun();
}
In most machine and in what I see in the web, we should compile like this:
g++ main.cpp 1.cpp
But in my machine, I must compile like this:
g++ 1.cpp main.cpp
what's wrong with my machine or my gcc?
I think you are facing the static initialization order fiasco which is a classical C++ bug. If initialization function test() in main.cpp is called before constructor for A::_instance has been called, your code will access uninitialized A::_instance::test_map field which is likely to cause segmentation fault. I suggest you rewrite getInstance to create instance when needed:
A *A::_instance;
A& A::get_instance() {
cout << "A::get_instance()\n";
if(!_instance)
_instance = new A;
return *A::_instance;
}
As a side note, I suggest you to use AddressSanitizer to autodetect this and similar types of errors.
everyone!
I want to get the return value of the shell command "ls" in a kernel module.
the following is the source code of my kernel module.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("yuuyuu");
MODULE_DESCRIPTION("kernel module hello");
MODULE_VERSION("1.0");
static int hello_init(void)
{
char * envp[] = { "HOME=/", NULL };
char * argv[] = { "/bin/ls","/home", NULL };
call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
printk(KERN_ALERT "hello_init() start\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "hello_exit() start\n");
}
module_init(hello_init);
module_exit(hello_exit);
Is there anyone know how to get the output of "ls /home"?
Thanks!
I am trying to compile multiple source files into a single module. I am having issues with multiple definition of functions.
Here is the code snippet of file1.c file
#include <linux/init.h>
#include <linux/module.h>
#include "headerfile.h"
#include <linux/slab.h>
static void swarm_init(void)
{
printk(KERN_ALERT "swarm_init function called\n");
}
void* func1(void) {
.....some code here
}
static void swarm_exit(void)
{
printk(KERN_ALERT "swarm_exit: exit function called");
}
module_init(swarm_init);
module_exit(swarm_exit);
Second file is as follows
#include <linux/init.h>
#include <linux/module.h>
#include "headerfile.h"
#include <linux/slab.h>
static void test_init(void)
{
printk(KERN_ALERT "Test init\n");
void *x;
x = func1();
}
static void test_exit(void)
{
printk(KERN_ALERT "test: exit function called");
}
module_init(test_init);
module_exit(test_exit);
headerfile.h is as follows
#ifndef _HEADERFILE_H
#define _HEADERFILE_H
typedef struct _hashmap_element{
int key;
int in_use;
void* data;
} hashmap_element;
typedef struct _hashmap_map{
int table_size;
int size;
hashmap_element *data;
} hashmap_map;
void *func1(void);
#endif
And my makefile is
obj-m :=myfile.o
myfile-objs := file1.o file2.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I keep getting multiple definition of init_module and cleanup_module.
any idea whats going wrong?
Single module may have at most one initialization (declared with module_init() macro) and one cleanup (module_exit()) function. If you need initialization functionality for several parts of your module, you need to combine them manually into single initialization function. The same is true for cleanup.
I followed the directions exactly as they are on this site here
http://www.newosxbook.com/src.jl?tree=listings&file=4-5-interpose.c
Here is the code from that page
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <malloc/malloc.h> // for malloc_printf()
// Note: Compile with GCC, not cc (important)
//
//
// This is the expected interpose structure
typedef struct interpose_s { void *new_func;
void *orig_func; } interpose_t;
// Our prototypes - requires since we are putting them in
// the interposing_functions, below
void *my_malloc(int size); // matches real malloc()
void my_free (void *); // matches real free()
static const interpose_t interposing_functions[] \
__attribute__ ((section("__DATA, __interpose"))) = {
{ (void *)my_free, (void *)free },
{ (void *)my_malloc, (void *)malloc }
};
void *
my_malloc (int size) {
// In our function we have access to the real malloc() -
// and since we don’t want to mess with the heap ourselves,
// just call it
//
void *returned = malloc(size);
// call malloc_printf() because the real printf() calls malloc()
// // internally - and would end up calling us, recursing ad infinitum
malloc_printf ( "+ %p %d\n", returned, size); return (returned);
}
void
my_free (void *freed) {
// Free - just print the address, then call the real free()
malloc_printf ( "- %p\n", freed); free(freed);
}
#if 0
From output 4-11:
morpheus#Ergo(~)$ gcc -dynamiclib l.c -o libMTrace.dylib -Wall // compile to dylib
morpheus#Ergo(~)$ DYLD_INSERT_LIBRARIES=libMTrace.dylib ls // force insert into ls
ls(24346) malloc: + 0x100100020 88
ls(24346) malloc: + 0x100800000 4096
ls(24346) malloc: + 0x100801000 2160
ls(24346) malloc: - 0x100800000
ls(24346) malloc: + 0x100801a00 3312 ... // etc.
#endif
Is there something different about the latest version of OSX or the code written here? It did not seem to intercept anything.
add attribute((used)) before the interposing_functions definition, and it will work, as follow:
// Note: Compile with GCC, not cc (important)
//
//
// This is the expected interpose structure
typedef struct interpose_s { void *new_func;
void *orig_func; } interpose_t;
// Our prototypes - requires since we are putting them in
// the interposing_functions, below
void *my_malloc(int size); // matches real malloc()
void my_free (void *); // matches real free()
__attribute__((used)) static const interpose_t interposing_functions[] \
__attribute__ ((section("__DATA, __interpose"))) = {
{ (void *)my_free, (void *)free },
{ (void *)my_malloc, (void *)malloc }
};
void *
my_malloc (int size) {
....
It's not a feature of Mavericks, it's a feature of clang. If you use jtool , from the same website, you'll see the generated dylib has no _DATA._interpose, which is required for DYLD to work the interposition magic.
Incidentally, this question is best asked in that book's own forum. That's probably what it's there for.