I need to call a function (an LLVM JIT to be specific) from a C++ application. This call might fail or even signal abort() or exit(). How can I avoid or at least reduce effects on my host application? Someone suggested using fork(), however I need a solution for both windows and posix. Even if I would use fork() ... would it be possible for the two processes to communicate (pass some pointers around)?
You basically have to isolate the call that might fail spectacularly, so yes, you probably have to create a separate process for it. I'd actually be tempted to create a small executable just containing this particular call and the necessary supporting functionality and call that from your main executable. This gets you around the lack of fork() on Windows and allows you to use the same mechanisms to communicate.
You can't pass pointers around between processes as they're not sharing the same address space. What I would do is have the spawned process reading data from stdin and write to stdout with the controlling process piping data into the child's stdin and reading from the child's stdout. Basically the way a Unix (command line) filter works. Another alternative if you're passing around a lot of data would be to write/read to/from a file on disk (better, a RAM disk) and communicate that way, but unless you're talking a lot of data, that's overkill.
As Eugen pointed out in the comments, you can also use shared memory if you want to pass pointers around or another inter-process communication mechanism depending on how much data you need to pass around. That said, choose the simplest possible method as nested executables like these aren't that easy to debug in the first place.
Related
I want to change the timezone for Linux system. I know there are many ways.
One way is to use tzset() function and another is to call 'timedatectl' command from 'popen()' function.
I am using second approach i.e, using "popen()".
I just want to ask is it a good programming practice to use "popen()" in your code?
Also, I am carefully calling "pclose()" for every "popen()".
There is nothing wrong about popen in general, if you really need a child process to do a specific job for you.
popen creates a pipe allowing you to either read the output (what it wrote to stdout) of the child process or write input to its stdin - but not both at the same time.
If you are not interested in either option, you possibly might prefer calling system instead (however, system will wait for the process to terminate, in contrast to popen - pclose waits for).
But why would you want to create a separate process, if you can do the same job by simply calling an ordinary function (system call or not)? You are creating a lot of overhead using a process then (process must be initialised and hooked into OS, it needs its own memory for executable code, heap and stack, ...)!
It gets a little more complicated, if the job in question requires a considerable amount of time and you cannot afford to wait for the function to complete, but need to do some other stuff. However, in such a case, I'd rather create a thread only and again call the function from there...
popen() invokes a shell to run the command which is an extra unnecessary layer of indirection. Plus there are all sorts of security pitfalls, for instance, you don't have control over the environment - or which shell actually gets invoked.
I'd say it's fine for prototypes and proofs of concept, but for production code you should use fork(), one of the execs and pipes for IO.
EDIT
If there is a function equivalent to doinf something by invoking a command, always use that first. For example, if you can achieve what you want with tzset(), always use that in preference to spawning a new process.
In C you can create multi process application using fork() and you can then communicate using a FIFO pipe. I have learned that C++ only supports multi threaded applications and if you want a multi-process application you have to rely on fork().
But in C++ type checking is crucial so I can't just pipe objects through a pipe without any risks. You could cast to void* and ask sizeof and the send everything through a pipe to typecast it back to the original object.
So why does this feel so wrong? Is multi-process architecture not used in C++ or are there libraries or better ways of doing things. I have googled a little and the only thing you find is multithreaded C++ or multi-process C.
The reason for wanting more processes is that I want my application to be as robust as possible. If my web service crashes I want my main process to restart it. There is no way of doing this multithreaded since you never know if 1 thread hasn't corrupted memory in another thread so if you get an error in one thread you have to restart out of safety.
I assume by multiprocess programs you mean concurrently running two separate instances of a program with some shared data between them. Communicating between processes can be tricky. I have always gotten by with the pipe-typecasting method you described, or by using a local socket system to send data back and forth, however there do exist libraries for higher-level communication between processes, see boost.interprocess I would give that a look, and see if it can fit your needs.
As far as I understand your question right your main problem is passing data from one process to another via some kind of serial connection.
If this is the case and you are just passing flat data structures up and down the line there should be no problem using the method you already described. Just shot the whole bunch of bits down the line and cast to the corresponding type on the other end of the line. As far as you're only communicating with processes running on the same machine with executables generated by the same compiler and with same compiler switches there won't be any problem with byte-order, member alignment or whatever.
If on the other hand your data is more complex containing some kind of references to other objects lists of dynamic length or the like then you'll soon get into big trouble using the simple cast to void* and pump the data bit by bit strategy. So you'll definately need a more sophisticated approach at "serialization" and "deserialization" of your objects.
These ("serialization" and "deserialization") are the two terms you might want to investigate further on to find the approach that best fits your problem.
As you'll soon find out these are problems to which "solutions" are invented over and over again with such a zoo of standards like XDR used by sun RPC and ASN.1 to name just a few that it is hard to tell which one will best fit to your use case.
If you're going with C++ you might want to take a look at the solution the boost has to offer (see: http://www.boost.org/doc/libs/1_39_0/libs/serialization/doc/index.html)
Yet again - if it's just flat data structures you're passing back and forth don't bother with any overhead of that kind and just shoot the data down the line bit by bit.
I would need help with a problem. I have 2 processes running, one the Watchdog and the other a simple test process. I need process 2 to call code from the Watchdog, the reason I do this is to reduce the size of process 2. For example process 2 must call a function called "IsSafe" from the watchdog. The IsSafe function relies on other code belonging to Watchdog process and it will not be viable to rewrite this code for process 2. I have thought of ideas, please could you advise on which is the best solution and or give advice.
Idea One
Use Named pipes to communicate between processes and pass parameters and return values around.
Idea Two
Use Share Memory to share parameters and return values
Idea Three
Use windows messages, I honestly think this will not work
Idea Four
Somehow create a executable portion of shared memory and execute this code with a far jmp.
Please could you advise.
RPC was invented long ago. Then COM on top of that. In my opinion best forget your idea, but if you must, use COM.
By the way, to communicate between processes on the same Windows machine without COM, use mailslots.
Seems you forgot about them in you list.
Cheers & hth.,
Although putting the code in the process which needs to call it is good advice in general, in the particular case of a watchdog (also debugger and any other form of error handler) using separate processes is correct. You don't want the watchdog to fail due to an error in the main code, so it needs to be a separate process.
A named pipe would be ideal in this scenario, the TransactNamedPipe function is designed just for this.
A DLL is the standard implementation of idea 4. It's loaded in both address spaces, but shared in physical RAM. You don't need special tricks; it works everywhere and Windows will deal with any security issues for you.
It's also portable to most other Operating Systems, although they're generally called something else, e.g. .so on Linux.
All you really need is some IPC. For a lightweight and easy solution, simply define an application specific message with WM_APP and have a mapping from the wParam/lParam for parameters. If you find you need more than 8 bytes, you could use WM_COPYDATA instead.
I have a very simple interface which needs to communicate between processes. It's currently implemented in a very simple manner (all single proc):
bool GetFoo(struct Foo *outFoo);
bool GetBar(struct Bar *getBar);
Such as:
Foo foo;
if (!GetFoo(&foo))
{
ReportError();
}
GetFoo fills out the "Foo" data structure with pure data (that is, no pointers - it's purely blitable data).
I need to convert this in-process function call to be between two processes on the same machine (in this case it's always the same machine). Is there a commonly followed idiom for cross-process calls in C++ on Windows? Is there some kind of intra-process communication supported by Windows? Should I be using shared memory instead?
One note: I don't want to take a dependency on anything other than the Windows APIs if at all possible.
You have many choices, but in my personal experience the most popular/easy to use ones are: sockets & pipes.
See here for all IPC options available for Windows.
I'm not sure what the most common is -- to truly answer that we'd have to have some kind of polling. That said, the most flexible way would probably be to expose the methods via DCOM.
A common method would be RPC, it can be implemented in various ways for instance as Billy mentioned using COM` (or DCOM if the processes are residing on different machines).
Although you may want to think about not doing direct RPC calls and instead have a named pipe between your processes which is used for the communication.
There are a number of ways to communicate between processes on the same computer in Windows. Which one works best depends on the relationship between the two processes. Is one process expected to start the other? In that case an out-of-process COM server would probably work best, since you can restart the other process if it is not already running.
If performance is critical, then shared memory will give you the most control the speed of passing the data between your processes.
One thing to think about is the failure semantics of running multiple processes. What does the calling process do if the callee is not there?
I have a count variable that should get counted up by a few processes I forked and used/read by the mother process.
I tried to create a pointer in my main() function of the mother process and count that pointer up in the forked children. That does not work! Every child seems to have it's own copy even though the address is the same in every process.
What is the best way to do that?
Each child gets its own copy of the parent processes memory (at least as soon as it trys to modify anything). If you need to share betweeen processes you need to look at shared memory or some similar IPC mechanism.
BTW, why are you making this a community wiki - you may be limiting responses by doing so.
2 processes cannot share the same memory. It is true that a forked child process will share the same underlying memory after forking, but an attempt to write to this would cause the operating system to allocate a new writeable space for it somewhere else.
Look into another form of IPC to use.
My experience is, that if you want to share information between at least two processes, you almost never want to share just some void* pointer into memory. You might want to have a look at
Boost Interprocess
which can give you an idea, how to share structured data (read "classes" and "structs") between processes.
No, use IPC or threads. Only file descriptors are shared (but not the seek pointer).
You might want to check out shared memory.
the pointers are always lies in the same process. It's private to the process, relative to the process's base address. There different kind of IPC mechanisms available in any operating systems. You can opt for Windows Messaging, Shared memory, socket, pipes etc. Choose one according to your requirement and size of data. Another mechanism is to write data in target process using Virtual memory APIs available and notify the process with corresponding pointer.
One simple option but limited form of IPC that would work well for a shared count is a 'shared data segment'. On Windows this is implemented using the #pragma data_seg directive.
See this article for an example.