February 18, 2015
On Wed, 18 Feb 2015 21:21:10 +0000, Byron Heads wrote:

> My guess is this is going to be related to forking, going to see if I can make a test case.

it's better to avoid forking at all. it's *very* hard to do forking right, it's almost impossible to do it right even in single-threaded app, and it's impossible to do it right in multithreaded app. `fork()` is a can full of worms, it may surprise you even on seemingly simple code.

i suggest you to just drop forking and use shell script instead. you can lost alot of time trying to force your forked code to work right, and then it will break again on any move (or even when moon will change it's phase).

February 18, 2015
On Wed, 18 Feb 2015 21:21:10 +0000, Byron Heads wrote:

p.s. if you really-really-really need to avoid shell scripts, you can `exec` your program with STDIN, STDOUT and STDERR redirected to /dev/ null, passing some special argument to it. i.e. it shouldn't fork, just exec itself again with added command-line option. just make sure that you did `setsid()` and so on, so the second instance is completely detached.

February 19, 2015
On Wednesday, 18 February 2015 at 21:21:11 UTC, Byron Heads wrote:
> On Wednesday, 18 February 2015 at 21:05:10 UTC, Byron Heads wrote:
>> On Wednesday, 18 February 2015 at 20:55:56 UTC, ketmar wrote:
>>> On Wed, 18 Feb 2015 20:35:44 +0000, Byron Heads wrote:
>>>
>>>> On Wednesday, 18 February 2015 at 20:33:40 UTC, ketmar wrote:
>>>>> On Wed, 18 Feb 2015 20:27:07 +0000, Byron Heads wrote:
>>>>>
>>>>> are you forking? ;-)
>>>> 
>>>> 
>>>> I am in the daemonize library
>>>> 
>>>> https://github.com/NCrashed/daemonize
>>>
>>> can you drop that and just let the program run on foreground? i suspect
>>> that it may solve your problem. you can detach your program with "setsid"
>>> and "&" to avoid forking.
>>>
>>> `fork()` is a very fragile thing, and it may be the source of heisenbugs.
>>> stop `fork()`ing may be the easiest solution (if it solves something, of
>>> course ;-).
>>
>> By passing daemonize with the GC enabled is working.. going to dig into the signals and see if thats it.
>
>
>
> My guess is this is going to be related to forking, going to see if I can make a test case.


Now I am not sure. This code runs correctly:

import std.stdio;
import std.concurrency;
import core.sys.posix.unistd;
import core.sys.posix.sys.stat;
import core.memory;
import std.c.linux.linux;

extern(C) nothrow {
	int __libc_current_sigrtmin();
	int close(int rd);
}

void  foo(Tid tid) {
	writeln("1");
	foreach(i; 0..1024) {
		ubyte[] buffer = new ubyte[](8_192);
		auto f = new float[1024];
		GC.collect;
	}

	writeln("2");

	send(tid, true);
	
}

extern(C) void sigsig(int sig) nothrow pure @system @nogc {

}



void main() {
	auto pid = fork();
	if(pid < 0) {
		writeln("fork failed");
	} if (pid > 0) {
		writeln("Spawned ", pid);
		return;
	}
	
	umask(0);
	auto sid = setsid();
	if(sid < 0) {
		writeln("failed to set sid");
	}

	assert(signal(SIGABRT, &sigsig) != SIG_ERR);
	assert(signal(SIGTERM, &sigsig) != SIG_ERR);
	assert(signal(SIGQUIT, &sigsig) != SIG_ERR);
	assert(signal(SIGINT, &sigsig) != SIG_ERR);
	assert(signal(SIGQUIT, &sigsig) != SIG_ERR);
	assert(signal(SIGHUP, &sigsig) != SIG_ERR);
	assert(signal(__libc_current_sigrtmin+1, &sigsig) != SIG_ERR);

	writeln("spawning");
	spawn(&foo, thisTid);
	spawn(&foo, thisTid);
	spawn(&foo, thisTid);

	foreach(i; 0..1024) {
		auto x = new long[1024];
		GC.collect;
	}

	receiveOnly!bool;
	receiveOnly!bool;
	receiveOnly!bool;

	GC.collect;
	writeln("done");
}



February 19, 2015
On Thu, 19 Feb 2015 16:33:58 +0000, Byron Heads wrote:

> Now I am not sure. This code runs correctly:

as i told you before, `fork()` is hard. you can experiment for monthes seeing strange bugs here and there, and seeing no bugs, and strange bugs, and...

there are alot of things going on under the hood, and alot of things aren't. strictly speaking you *CAN'T* get cloned process in the same state as it's parent. it may work, though, if stars are in a good shape.

i can give you a simple test that will tell you if you should avoid `fork ()` in your code: unless you can explain what is going on in kernel, glibc, pthreads and druntime exactly in the moment of forking, without looking to mans, documentation and source code of all components -- avoid using `fork()`. i can explain ~2/3, so i'm not using `fork()` in my code. ;-)

February 19, 2015
On 2/19/15 12:01 PM, ketmar wrote:
> On Thu, 19 Feb 2015 16:33:58 +0000, Byron Heads wrote:
>
>> Now I am not sure. This code runs correctly:
>
> as i told you before, `fork()` is hard. you can experiment for monthes
> seeing strange bugs here and there, and seeing no bugs, and strange bugs,
> and...

>
> there are alot of things going on under the hood, and alot of things
> aren't. strictly speaking you *CAN'T* get cloned process in the same
> state as it's parent. it may work, though, if stars are in a good shape.

Just as an example, Sociomantic uses a concurrent GC based on forking.

I'm not sure what the issue here is, but I don't think forking is as unstable as you seem to think, or maybe I'm reading this wrong. I can agree there are many gotchas with forking.

-Steve
February 19, 2015
On Thu, 19 Feb 2015 17:12:02 -0500, Steven Schveighoffer wrote:

> On 2/19/15 12:01 PM, ketmar wrote:
>> On Thu, 19 Feb 2015 16:33:58 +0000, Byron Heads wrote:
>>
>>> Now I am not sure. This code runs correctly:
>>
>> as i told you before, `fork()` is hard. you can experiment for monthes
>> seeing strange bugs here and there, and seeing no bugs, and strange
>> bugs,
>> and...
> 
> 
>> there are alot of things going on under the hood, and alot of things aren't. strictly speaking you *CAN'T* get cloned process in the same state as it's parent. it may work, though, if stars are in a good shape.
> 
> Just as an example, Sociomantic uses a concurrent GC based on forking.

it's completely different thing. *this* use of fork -- to make "snapshot" of running application -- is perfectly ok.

> I'm not sure what the issue here is, but I don't think forking is as unstable as you seem to think, or maybe I'm reading this wrong. I can agree there are many gotchas with forking.

forking is stable -- in the sense that it's doing exactly what it was asked to do. but that can be something different from what someone *think* it should do. `fork()` is described as "making a copy of the running process", and it's right... for some extent. but what "copy" is exactly? all threads except the one are lost. pid and tid was changed. what about signal masks? and thousands of other things which are taken as granted -- thread locks, for example, which can store tid of the thread that was aquired the lock? what about other libraries, which can do things you don't know about? and so on...

sure, `fork()` is perfectly usable... when you know what is going on and can foresee all consequences. but it's hard, and i'd better recommend to avoid `fork()` at all if programmer is not closely familiar with the thing. in most cases avoiding `fork()` is much easier than trying to find out what (can/is) going wrong with the program that was working ok without forking.

what i trying to tell OP is that if his code working ok without forking, it's much easier to just go this way and forget about `fork()`, not wasting time to find out what is wrong with it.

February 20, 2015
I think, it's better to diagnose, what problem the program encounters, than to explain, what happens in kernel and glibc. The first step is to see, where it hangs and get a stacktrace.
February 20, 2015
On Thursday, 19 February 2015 at 22:12:03 UTC, Steven Schveighoffer wrote:
> I'm not sure what the issue here is, but I don't think forking is as unstable as you seem to think, or maybe I'm reading this wrong. I can agree there are many gotchas with forking.

You need to very carefully configure what happens to resources before/after forking. So if you use third party libraries with threading all bets are off... If you fork early in the process' lifespan, before acquiring resources, then it is much easier...

http://linux.die.net/man/2/fork
February 20, 2015
On Fri, 20 Feb 2015 08:03:00 +0000, Kagamin wrote:

> I think, it's better to diagnose, what problem the program encounters,
> than to explain, what happens in kernel and glibc.
> The first step is to see, where it hangs and get a stacktrace.

this way of thinking is exactly why i recommend to avoid `fork()` unless one can explain *everything* it does.

February 20, 2015
On Fri, 20 Feb 2015 09:04:29 +0000, Ola Fosheim Grøstad wrote:

> If you fork early in the process'
> lifespan, before acquiring resources, then it is much easier...

and even if `fork()` is the first line of code in `main()`, there cannot be any guarantees. there can be module constructor doing something, or 3rd party library that already initialized something, or... you got the idea. ;-)