Register function that will be called before system call - operating-system

How can we register function such that it will be called before executing system call.
For example, pthread_atfork() registers functions that will be called before and after fork().
Below is the example on Linux system.
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
//http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html
void prepare_function() {
printf("%d : In Prepare Function\n", getpid());
}
void parent_fuction() {
printf("%d : In Parent Function\n", getpid());
}
void child_function() {
printf("%d : In Child Function\n", getpid());
}
int main() {
pthread_atfork(prepare_function, parent_fuction, child_function);
if (fork() == 0) {
//sleep(1);
printf("%d : In Child\n", getpid());
return 0;
}
//sleep(1);
printf("%d : In Parent\n", getpid());
return 0;
}
I'm curious about how this can be implemented.

What is the actual goal here?
Fork has hooks because the state of the child with presence of threads in undefined. So by hooking yourself up you can ensure whatever mechanisms you want to use remain operational (for instance, if the fork happened after one of your threads takes a lock, the lock will remain taken within the child - what now?).
In general there is no mechanism which provides hooks for all syscalls.
For the most part syscalls are wrapped in glibc so there are few entry points which actually call the kernel. Someone bored enough could hack this up by e.g. inserting a jump in generated code to which would land the execution in their routine. But such a routine would have to have its own way of calling syscalls or a hack.
But wait, any piece of code is free to call a syscall without the use of such wrappers and such code could be dynamically generated, so you can't binary patch it prior to execution.
You can trace syscall entry/exit with ptrace, but you need a separate process for that.

Related

What operations are unsafe before __libc_init_array is invoked?

I want to run some code before main begins, and before constructors for static variables run. I can do with with code like this (ideone)
extern "C" {
static void do_my_pre_init(void) {
// something
}
__attribute__ ((section (".preinit_array"))) void(*p_init)(void) = &do_my_pre_init;
}
Are there any language features that will not work correctly when executed in this function, due to _init and .init_array not yet having been executed?
Or is it only user code that should be hooking into this mechanism?
Some background on __libc_init_array
The source for a typical __libc_init_array is something like:
static void __libc_init_array() {
size_t count, i;
count = __preinit_array_end - __preinit_array_start;
for (i = 0; i < count; i++)
__preinit_array_start[i]();
_init();
count = __init_array_end - __init_array_start;
for (i = 0; i < count; i++)
__init_array_start[i]();
}
Where the __... symbols come from a linker script containing
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
Are there any language features that will not work correctly when executed in this function, due to _init and .init_array not yet having been executed?
This question is impossible to answer in general, because the language itself has no concept of .preinit_array, or _init, or .init_array. All of these concepts are implementation details for a particular system.
In reality, you aren't guaranteed to have anything work at all. Things as simple as malloc may not work (e.g. because the malloc subsystem itself may be using .preinit_array to initialize itself).
In practice, using dynamic linking on a GLIBC-based platform most everything will work (because libc.so.6 initializes itself long before the first instruction of the main executable runs).
For fully-static executable, all bets are off.
For non-GLIBC platform, you'll need to look into specifics of that platform (and you are very unlikely to find any guarantees).
Update:
Can I make function calls,
Function calls need no setup with fully-static linking, and need dynamic loader to have initialized in dynamic linking case. No dynamic loader will start executing code in the application before it has fully initialized itself, so function calls should be safe.
assign structs
In C, at best, this is a few instructions. At worst, this is a call to memcpy or memset. That should be safe.
use array initializers.
This is just a special case of struct assignment, so should be safe.

Event-driven design with callbacks in Rust

I'd like to know how a composable event-driven design with callbacks can be used in Rust. From my existing experimentation, I have come to suspect that the ownership system in Rust is more suited to top-down procedural code and has problems with references to parent objects that are needed for callbacks in event-driven design.
Essentially, I would like to see the Rust equivalent for the following C++ code. The code implements an EventLoop which dispatches Timer events using a busy-loop, a Timer class with a timer_expired callback, and a User class that schedules a timer in intervals of 500ms.
#include <stdio.h>
#include <assert.h>
#include <list>
#include <chrono>
#include <algorithm>
using namespace std::chrono;
// Wrapping code in System class so we can implement all functions within classes declarations...
template <typename Dummy=void>
struct System {
class Timer;
class EventLoop {
friend class Timer;
private:
std::list<Timer *> m_running_timers;
bool m_iterating_timers;
typename std::list<Timer *>::iterator m_current_timer;
void unlink_timer (Timer *timer)
{
auto it = std::find(m_running_timers.begin(), m_running_timers.end(), timer);
assert(it != m_running_timers.end());
if (m_iterating_timers && it == m_current_timer) {
++m_current_timer;
}
m_running_timers.erase(it);
}
public:
EventLoop()
: m_iterating_timers(false)
{
}
milliseconds get_time()
{
return duration_cast<milliseconds>(system_clock::now().time_since_epoch());
}
void run()
{
while (true) {
milliseconds now = get_time();
m_iterating_timers = true;
m_current_timer = m_running_timers.begin();
while (m_current_timer != m_running_timers.end()) {
Timer *timer = *m_current_timer;
assert(timer->m_running);
if (now >= timer->m_expire_time) {
m_current_timer = m_running_timers.erase(m_current_timer);
timer->m_running = false;
timer->m_callback->timer_expired();
} else {
++m_current_timer;
}
}
m_iterating_timers = false;
}
}
};
struct TimerCallback {
virtual void timer_expired() = 0;
};
class Timer {
friend class EventLoop;
private:
EventLoop *m_loop;
TimerCallback *m_callback;
bool m_running;
milliseconds m_expire_time;
public:
Timer(EventLoop *loop, TimerCallback *callback)
: m_loop(loop), m_callback(callback), m_running(false)
{
}
~Timer()
{
if (m_running) {
m_loop->unlink_timer(this);
}
}
void start (milliseconds delay)
{
stop();
m_running = true;
m_expire_time = m_loop->get_time() + delay;
m_loop->m_running_timers.push_back(this);
}
void stop ()
{
if (m_running) {
m_loop->unlink_timer(this);
m_running = false;
}
}
};
class TimerUser : private TimerCallback {
private:
Timer m_timer;
public:
TimerUser(EventLoop *loop)
: m_timer(loop, this)
{
m_timer.start(milliseconds(500));
}
private:
void timer_expired() override
{
printf("Timer has expired!\n");
m_timer.start(milliseconds(500));
}
};
};
int main ()
{
System<>::EventLoop loop;
System<>::TimerUser user(&loop);
loop.run();
return 0;
}
The code works as standard C++14 and I believe is correct. Note, in a serious implementation I would make the running_timers an intrusive linked-list not a std::list for performance reasons.
Here are some properties of this solution which I need to see in a Rust equivalent:
Timers can be added/removed without restrictions, there are no limitations on how/where a Timer is allocated. For example one can dynamically manage a list of classes each using their own timer.
In a timer_callback, the class being called back has full freedom to access itself, and the timer it is being called from, e.g. to restart it.
In a timer_callback, the class being called also has freedom to delete itself and the timer. The EventLoop understands this possibility.
I can show some things I've tried but I don't think it will be useful. The major pain point I'm having is satisfy the borrowing rules with all the references to parent objects involved for callback traits.
I suspect a RefCell or something similar might be part of a solution, possibly one or more special classes with internal unsafe parts, that allow gluing stuff together. Maybe some parts of reference safety typically provided by Rust could only be guaranteed at runtime by panicking.
Update
I have created a prototype implementation of this in Rust, but it is not safe. Specifically:
Timers and the EventLoop must not be moved. If they are accidentally moves undefined behavior occurs due to use pointers to these. It is not possible to even detect this within Rust.
The callback implementation is a hack but should work. Note that this allows the same object to receive callbacks from two or more Timers, something that is not possible if traits were used for callbacks instead.
The callbacks are unsafe due to use of pointers that point to the object that is to receive the callback.
It is theoretically possible for an object to delete itself, but this actually seems unsafe in Rust. Because if a Timer callback ends up deleting itself, there would be a &self reference at one point that is not valid. The source of this unsafety is the use of pointers for callbacks.

On renderscripts and thread-safety

I have always assumed that renderscripts are threadsafe with forEach across an allocation. To aid in my debugging, can someone confirm this?
(I'm seeing a static array value check succeed, but using rsDebug shows that the check should have failed.
static uint32_t state[16];
static void f(); // modifies state.
/* snip... */
void
root(const uint32_t *in, uint32_t *out)
{
/* snip... */
f();
if(state[0] == 0)
{
rsDebug("state[0]", state[0]);
*out = 1;
}
}
I see printed state[0] with a nonzero value!)
Each cell is expected to execute independently of the other cells. If you are writing to other cells of your input (or output) Allocation, you can certainly trigger undefined behavior. This is no different than any other multithreaded computation model, however. Can you show your kernel code exactly and describe how you are calling it?

Call function in main program from a library in Arduino

I've just started making libraries in Arduino. I've made a library named inSerialCmd. I want to call a function named delegate() that is defined in the main program file, stackedcontrol.ino, after the inSerialCmd library is included.
When I try to compile, one error is thrown:
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp: In member function
'void inSerialCmd::serialListen()':
...\Arduino\libraries\inSerialCmd\inSerialCmd.cpp:32: error:
'delegate' has not been declared
After doing a bit of searching, it seemed that adding the scope resolution operator might do the trick. So I added the "::" before delegate(), now "::delegate()", but the same error is thrown.
Now I'm stumped.
You cannot and should not directly call a function in a program from a library. Keep in mind a key aspect that makes a library into a library:
A library does not depend on the specific application. A library can be fully compiled and packaged into the .a file without the existence of a program.
So there is a one way dependency, a program depends on a library. This at first glance may seem to prevent you from achieving what you want. You can achieve the functionality you are asking about through what is sometimes referred to as a callback. The main program would provide to the library at runtime a pointer to the function to execute.
// in program somwehere
int myDelegate(int a, int b);
// you set this to the library
setDelegate( myDelegate );
You see this in the arduino if you look at how interrupt handlers are installed. This same concept exists in many environments - event listeners, action adapters - all with the same goal of allowing a program to define the specific action that a library cannot know.
The library would store and call the function via the function pointer. Here is a rough sketch of what this looks like:
// in the main program
int someAction(int t1, int t2) {
return 1;
}
/* in library
this is the delegate function pointer
a function that takes two int's and returns an int */
int (*fpAction)(int, int) = 0;
/* in library
this is how an application registers its action */
void setDelegate( int (*fp)(int,int) ) {
fpAction = fp;
}
/* in libary
this is how the library can safely execute the action */
int doAction(int t1, int t2) {
int r;
if( 0 != fpAction ) {
r = (*fpAction)(t1,t2);
}
else {
// some error or default action here
r = 0;
}
return r;
}
/* in program
The main program installs its delegate, likely in setup() */
void setup () {
...
setDelegate(someAction);
...

Using classes with the Arduino

I'm trying to use class objects with the Arduino, but I keep running into problems. All I want to do is declare a class and create an object of that class. What would an example be?
On Arduino 1.0, this compiles just fine:
class A
{
public:
int x;
virtual void f() { x=1; }
};
class B : public A
{
public:
int y;
virtual void f() { x=2; }
};
A *a;
B *b;
const int TEST_PIN = 10;
void setup()
{
a=new A();
b=new B();
pinMode(TEST_PIN,OUTPUT);
}
void loop()
{
a->f();
b->f();
digitalWrite(TEST_PIN,(a->x == b->x) ? HIGH : LOW);
}
There is an excellent tutorial on how to create a library for the Arduino platform. A library is basically a class, so it should show you how its all done.
On Arduino you can use classes, but there are a few restrictions:
No new and delete keywords
No exceptions
No libstdc++, hence no standard functions, templates or classes
You also need to make new files for your classes, you can't just declare them in your main sketch. You also will need to close the Arduino IDE when recompiling a library. That is why I use Eclipse as my Arduino IDE.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1230935955 states:
By default, the Arduino IDE and
libraries does not use the operator
new and operator delete. It does
support malloc() and free(). So the
solution is to implement new and
delete operators for yourself, to use
these functions.
Code:
#include <stdlib.h> // for malloc and free
void* operator new(size_t size) { return malloc(size); }
void operator delete(void* ptr) { free(ptr); }
This let's you create objects, e.g.
C* c; // declare variable
c = new C(); // create instance of class C
c->M(); // call method M
delete(c); // free memory
Regards,
tamberg
I created this simple one a while back. The main challenge I had was to create a good build environment - a makefile that would compile and link/deploy everything without having to use the GUI. For the code, here is the header:
class AMLed
{
private:
uint8_t _ledPin;
long _turnOffTime;
public:
AMLed(uint8_t pin);
void setOn();
void setOff();
// Turn the led on for a given amount of time (relies
// on a call to check() in the main loop()).
void setOnForTime(int millis);
void check();
};
And here is the main source
AMLed::AMLed(uint8_t ledPin) : _ledPin(ledPin), _turnOffTime(0)
{
pinMode(_ledPin, OUTPUT);
}
void AMLed::setOn()
{
digitalWrite(_ledPin, HIGH);
}
void AMLed::setOff()
{
digitalWrite(_ledPin, LOW);
}
void AMLed::setOnForTime(int p_millis)
{
_turnOffTime = millis() + p_millis;
setOn();
}
void AMLed::check()
{
if (_turnOffTime != 0 && (millis() > _turnOffTime))
{
_turnOffTime = 0;
setOff();
}
}
It's more prettily formatted here: http://amkimian.blogspot.com/2009/07/trivial-led-class.html
To use, I simply do something like this in the .pde file:
#include "AM_Led.h"
#define TIME_LED 12 // The port for the LED
AMLed test(TIME_LED);
My Webduino library is all based on a C++ class that implements a web server on top of the Arduino Ethernet shield. I defined the whole class in a .h file that any Arduino code can #include. Feel free to look at the code to see how I do it... I ended up just defining it all inline because there's no real reason to separately compile objects with the Arduino IDE.
Can you provide an example of what did not work? As you likely know, the Wiring language is based on C/C++, however, not all of C++ is supported.
Whether you are allowed to create classes in the Wiring IDE, I'm not sure (my first Arduino is in the mail right now). I do know that if you wrote a C++ class, compiled it using AVR-GCC, then loaded it on your Arduino using AVRDUDE, it would work.