Reset dlmopen namespace - c++

I have a small program that loads 2 modules (X11, and my own):
#include <fcntl.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
int main(int c, char* argv[])
{
pid_t PID = c > 1 ? atoi(argv[1]) : -1;
if (PID <= 0)
{
fprintf(stderr, "Invalid PID\n");
return -1;
}
const char* path = "/home/brandon/Desktop/mylib.so";
void* x11 = dlmopen(LM_ID_NEWLM, "libX11.so.6", RTLD_NOW);
/*Lmid_t id = 0;
dlinfo(dl, RTLD_DI_LMID, &id);
dl = dlmopen(id, path, RTLD_LAZY);*/
void* dl = dlopen(path, RTLD_LAZY);
if (dl)
{
printf("Loading dll\n");
void (*ptrace_info)(pid_t pid) = (decltype(ptrace_info))dlsym(dl, "ptrace_info");
if (ptrace_info)
{
ptrace_info(PID);
}
dlclose(dl);
printf("Unloaded\n");
}
return 0;
}
If I use dlopen(path, RTLD_*) my module fails to ptrace the specified pid. However, if I uncommented the code above that uses dlmopen everything works fine (even if I create a new namespace, it works)..
If I do not dlmopen(.., X11, ..), it works fine. The only time it does NOT work is if I dlmopen anything and then try to dlopen something else.
Seeing as the only difference is the namespace, is there a way I can use dlopen after using dlmopen?

Related

error occur when I call execvp to run java

I use chdir() to switch the directory, and then use execvp() to execute "java Main". I'm sure there is Main.class, but something went wrong. I want to know why.
#include <cstdio>
#include <unistd.h>
using namespace std;
int main(){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/keane/Judge/temp");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3];
array[0] = "java";
array[1] = "Main";
array[2] = NULL;
execvp("java", array);
return 0;
}
the error is could not find the main class , and I can run java Main in that directory.
What drives me crazy is that I can't use system("java Main"), and the error is that Error: Could not find or load main class Main, and it's just like this on my computer
update:
#include <unistd.h>
#include <cstdlib>
int main(){
chdir("/home/keane/Judge/temp");
system("pwd");
system("ls");
system("java Main");
return 0;
}
the output on console is:
/home/keane/Judge/temp
1.out 3.out 5.out Main.class stdout_spj.txt
2.out 4.out ce.txt Main.java
Error: Could not find or load the main class Main
my final solution is to reboot the computer and add -cp . to the java command.
althought I don't why is necessary.
thanks everyone!
This works as intended on my system, maybe you need to add -cp . to your java call.
EDIT: to elaborate: -cp (for classpath) tells java where to look for user provided .class files. This does not necessarily include the current working directory by default.
The execution of execvp() is non-blocking and takes ownership of the caller, that means that when it starts if the program ends too quickly you will never be able to see the result, to solve this I use fork(). The wait is just to avoid using sleep as I used at the begining. Its all in c.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char** argv){
char buf[80];
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
chdir("/home/");
getcwd(buf,sizeof(buf));
printf("current working directory: %s\n", buf);
char *array[3] = {"java", "Main", NULL};
if(fork() == 0) {
if(execvp("java", array) < 0) {
fprintf(stderr, "Error spawning command: %s\n", strerror(errno));
}
} else {
printf("Command spawned\n");
wait(NULL); // Wait to the forked process to end (avoid using sleep)
}
return 0;
}

How do I fix this malloc() error in C++ when I am trying to load a kernel module?

I am getting the error malloc(): memory corruption when I execute this code in C++. Basically, I open a kernel file and I use malloc with the size of struct stat st. I guess this is causing the problem.
The code loads a kernel module (I2C) and it is actually loading. but I guess I am not using the malloc() as should be used. Thanks.
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
#define delete_module(name, flags) syscall(__NR_delete_module, name, flags)
class I2CKernelModule : public testing::Test {
public:
I2CKernelModule() {
}
};
TEST_F(I2CKernelModule, TestAddAndRemoveKernelModule) {
char *params;
int fd;
size_t image_size;
struct stat st;
void *image;
// command: sudo insmod /root/i2c-tests/i2c-stub.ko chip_addr=0x20
params = "chip_addr=0x20";
fd = open("/root/i2c-tests/i2c-stub.ko", O_RDONLY);
fstat(fd, &st);
image_size = st.st_size;
image = malloc(image_size);
read(fd, image, image_size);
close(fd);
if (init_module(image, image_size, params) != 0) {
perror("init_module");
GTEST_FAIL();
}
free(image);
GTEST_SUCCESS_("Kernel module loaded.");
/*
// sudo rmmod i2c_stub
if (delete_module("i2c_stub", O_NONBLOCK) != 0) {
perror("delete_module");
GTEST_FAIL();
}
GTEST_SUCCESS_("Kernel module unloaded.");
*/
}
Check the return values of all functions for errors. The code you have listed would fail if the file doesn't open, the stat fails or the malloc fails. It is also a good idea to check the number of bytes returned by read.

Cannot compile demo program using fork() and pipes() in C++

All, the first part of my homework assignment is simply a demo program that I need to compile, and then modify. It was provided by the teacher, however I simply cannot get it to compile using g++. I will be creating a make file at the end of the assignment, but for the moment I am simply trying to test it out, and am having no luck. I've tried the most basic g++ command: g++ -o main TwoPipesTwoChildren.cpp . Can someone please help? I can't even get started on this until I can get this working.
// description: This program will execute "ls -ltr | grep 3376"
// by using a parent and child process
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv){
printf("TEST");
int status;
int childpid;
char *cat_args[] = {"ls", "-ltr", NULL};
char *grep_args[] = {"grep", "3376", NULL};
// create one pipe to send the output of "ls" process to "grep" process
int pipes[2];
pipe(pipes);
// fork the first child (to execute cat)
if((childpid = fork()) == -1)
{
perror("Error creating a child process");
exit(1);
}
// replace cat's stdout with write part of 1st pipe
if (childpid == 0)
{
dup2(pipes[1], 1);
printf("AFTER FORK CHILD");
//close all pipes (very important!); end we're using was safely copied
close(pipes[0]);
close(pipes[1]);
execvp(*cat_args, cat_args);
exit(0);
}
else
{
// replace grep's stdin with read end of 1st pipe
dup2(pipes[0], 0);
close(pipes[0]);
close(pipes[1]);
execvp(*grep_args, grep_args);
}
return (0);
}

execute RFSniffer and codeSend in nodejs

Both tools are available over here: https://github.com/ninjablocks/433Utils/tree/master/RPi_utils
I really want a simple interface to manage my 433mhz devices. but i can't find a good one.
So I have worked all day now trying to make a wrapper for nodejs to the RCSwitch class. with 2 simple methods
- send[code]
- recieve[callback[code]]
I get this error when i try to make a new instance of the RCSwitch class.
node: symbol lookup error:
/root/nodemodule/example/build/Release/kaku.node:
undefined symbol: _ZN8RCSwitchC1Ev
It compiles perfectly with node-gyp but when I execute node it fails.
Now I use exec to execute sendCommand with the code. (UGLY I Know)
And I tried to make the RFSniffer work like this:
./RFSniffer > rfsniffer.log
.Then tail -f the rfsniffer.log
But RFSniffer wont give me any data.
So my question is can anybody help me to get RFsniffer working with tail -f
Or even beter can someone help me fix the c++ addon for nodejs:)
Here is the wrapper code:
#include "RCSwitch.h"
#include <node.h>
#include <v8.h>
using namespace v8;
Handle<Value> CodeSend(const Arguments& args) {
HandleScope scope;
int PIN = 0;
RCSwitch mySwitch = RCSwitch();
mySwitch.enableTransmit(PIN);
mySwitch.send(args[0]->IntegerValue(), 24);
return scope.Close(True());
}
Handle<Value> CodeRecieve(const Arguments& args) {
HandleScope scope;
// Entry check
if (args.Length() != 2) {
ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
return scope.Close(Undefined());
}
Local<String> name= args[0]->ToString();
Local<String> msg = name;
Local<Function> cb = Local<Function>::Cast(args[1]);
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(msg) };
cb->Call(Context::GetCurrent()->Global(), argc, argv);
return scope.Close(Undefined());
}
extern "C" {
static void init(Handle<Object> target) {
if( wiringPiSetup() == -1 ) {
ThrowException( Exception::TypeError( String::New( "rcswitch: GPIO initialization failed" ) ) );
return;
}
NODE_SET_METHOD(target, "Send", CodeSend);
NODE_SET_METHOD(target, "Recieve", CodeRecieve);
}
NODE_MODULE(kaku, init);
}
nodejs code:
var addon = require('./build/Release/kaku');
console.log(addon.Send(1234));
addon.Recieve(1234, function (val) {
console.log(val);
});
I had the same problem than you and the reason why ./RFSniffer > rfsniffer.log doesn't work is that printf() function in RFSniffer code is not flushed.
Try with this source code :
/*
RF_Sniffer
Hacked from http://code.google.com/p/rc-switch/
by #justy to provide a handy RF code sniffer
*/
#include "RCSwitch.h"
#include <stdlib.h>
#include <stdio.h>
RCSwitch mySwitch;
int main(int argc, char *argv[]) {
// This pin is not the first pin on the RPi GPIO header!
// Consult https://projects.drogon.net/raspberry-pi/wiringpi/pins/
// for more information.
int PIN = 2;
if(wiringPiSetup() == -1)
return 0;
mySwitch = RCSwitch();
mySwitch.enableReceive(PIN); // Receiver on inerrupt 0 => that is pin #2
while(1) {
if (mySwitch.available()) {
int value = mySwitch.getReceivedValue();
if (value == 0) {
printf("Unknown encoding");
} else {
printf("Received %i\n", mySwitch.getReceivedValue() );
}
fflush(stdout); // Add this line to flush the previous printf()
mySwitch.resetAvailable();
}
}
exit(0);
}
And if you run the RFSniffer tool with sudo permission, you can execute with :
sudo ./RFSniffer | sudo tee rfsniffer.log
OR
sudo sh -c './RFSniffer >> rfsniffer.log'

Replacing getpid with my own implementation

I have an application where I need to write a new getpid function to replace the original one of the OS. The implementation would be similar to:
pid_t getpid(void)
{
if (gi_PID != -1)
{
return gi_PID;
}
else
{
// OS level getpid() function
}
}
How can I call the original getpid() implementation of the OS through this function?
EDIT: I tried:
pid_t getpid(void)
{
if (gi_PID != -1)
{
return gi_PID;
}
else
{
return _getpid();
}
}
as Jonathan has suggested. This gave me the following errors when compiling with g++:
In function pid_t getpid()':
SerendibPlugin.cpp:882: error:
_getpid' undeclared (first use this
function) SerendibPlugin.cpp:882:
error: (Each undeclared identifier is
reported only once for each function
it appears in.)
EDIT 2: I've managed to get this to work by using a function pointer and setting it to the next second symbol with the id "getpid", using dlsym(RTLD_NEXT, "getpid").
Here's my sample code:
vi xx.c
"xx.c" 23 lines, 425 characters
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <dlfcn.h>
using namespace std;
pid_t(*___getpid)();
pid_t getpid(void)
{
cout << "My getpid" << endl;
cout << "PID :" << (*___getpid)() << endl;
return (*___getpid)();
}
int main(void)
{
___getpid = (pid_t(*)())dlsym(RTLD_NEXT, "getpid");
pid_t p1 = getpid();
printf("%d \n", (int)p1);
return(0);
}
g++ xx.c -o xout
My getpid
PID :7802
7802
On many systems, you will find that getpid() is a 'weak symbol' for _getpid(), which can be called in lieu of getpid().
The first version of the answer mentioned __getpid(); the mention was removed swiftly since it was erroneous.
This code works for me on Solaris 10 (SPARC) - with a C++ compiler:
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
extern "C" pid_t _getpid();
pid_t getpid(void)
{
return(-1);
}
int main(void)
{
pid_t p1 = getpid();
pid_t p2 = _getpid();
printf("%d vs %d\n", (int)p1, (int)p2);
return(0);
}
This code works for me on Solaris 10 (SPARC) - with a C compiler:
Black JL: cat xx.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
pid_t getpid(void)
{
return(-1);
}
int main(void)
{
pid_t p1 = getpid();
pid_t p2 = _getpid();
printf("%d vs %d\n", (int)p1, (int)p2);
return(0);
}
Black JL: make xx && ./xx
cc xx.c -o xx
"xx.c", line 13: warning: implicit function declaration: _getpid
-1 vs 29808
Black JL:
You can use a macro:
in a .h, included in every file where you want to replace the getpid function
#define getpid() mygetpid()
Then, put your own implementation in a .cpp
pid_t mygetpid() {
// do what you want
return (getpid)();
}
You're using the terminology a bit incorrectly. It's not possible to override getpid() because it's not a virtual function. All you can do is attempt to replace getpid with a different function by various evil means.
But I must ask, why are you doing this? Replacing getpid means that any component which was depending on the return of getpid will now be receiving you're presumably modified result. This change has a very high risk of changing some other component.
What you're offering is a new functionality and hence should be a different function.
That being said if you truly want to take this approach the best way is to dynamic loading of the function. The original DLL will still contain the getpid function and you can access that via a combination of LoadLibrary/GetProcAddress on Windows or dlopen/dlsym on Linux. If you're using a different OS please specify.
EDIT Responding to comments that getpid needs to be testable
If testing is the concern then why not instead have a custom getpid method for you're application. For example, applicationGetPid(). For normal execution this could be forwarded off to the system getpid function. But during Unit Testing it could be used to produce more predictable values.
pid_t applicationGetPid() {
#if UNIT_TEST
return SomeCodeForUnitTests;
#else
return getpid();
#endif
}