Created attachment 1226
Sample crash log
The following code produces a program crash on Mac OS 10.8. Nothing is output
to the opened file and a crash is reported to /etc/log/system.log.
import core.sys.posix.unistd;
import std.c.stdlib;
import std.process;
import std.stdio;
import std.string;
int main(string[] args)
{
pid_t pid = fork();
if (pid < 0)
{
exit(EXIT_FAILURE);
}
if (pid > 0)
{
exit(EXIT_SUCCESS);
}
auto logFile = File("/Users/gary/Desktop/test.log", "a");
logFile.writeln("Opened file");
string command = format("logger -t %s %s", "hello", "This is a test");
executeShell(command);
logFile.writeln("Done");
return 0;
}
See attached for sample crash log.
Comment #1 by spam — 2013-06-15T12:20:52Z
Another example of maybe the same bug? This also crashes but does so silently with no system.log entry or crash dump.
import core.sys.posix.sys.stat;
import core.sys.posix.unistd;
import std.c.stdio;
import std.c.stdlib;
import std.process;
import std.stdio;
import std.string;
import std.file;
import std.datetime;
class Logger
{
private File _logFile;
public this(string logFile)
{
this._logFile = File(logFile, "a");
}
public void info(string, A...)(string text, A args)
{
this._logFile.writefln(format(text, args));
}
}
int main(string[] args)
{
pid_t pid, sid;
pid = fork();
if (pid < 0)
{
exit(EXIT_FAILURE);
}
if (pid > 0)
{
exit(EXIT_SUCCESS);
}
umask(0);
sid = setsid();
if (sid < 0)
{
exit(EXIT_FAILURE);
}
if ((core.sys.posix.unistd.chdir("/")) < 0)
{
exit(EXIT_FAILURE);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
auto logger = new Logger("/Users/gary/Desktop/test.log");
// Crash!
logger.info("Reading file");
string configFileContents = readText("/etc/hosts");
// Never executes!
logger.info(configFileContents);
return 0;
}
Comment #2 by post — 2013-07-28T08:11:16Z
I can not reproduce this on Linux. It would be great to get confirmation from someone else on OSX, to verify that it isn't a local issue.
One thing I've noticed is that you call exit() in the parent process after a successful fork(). You should call _exit() instead, to avoid double-flushing buffers etc. This probably won't fix your problem, but it's worth a try.
Comment #3 by spam — 2013-07-28T08:37:03Z
(In reply to comment #2)
> I can not reproduce this on Linux. It would be great to get confirmation from
> someone else on OSX, to verify that it isn't a local issue.
>
> One thing I've noticed is that you call exit() in the parent process after a
> successful fork(). You should call _exit() instead, to avoid double-flushing
> buffers etc. This probably won't fix your problem, but it's worth a try.
I've reduced it to this:
import std.stdio;
import std.string;
import std.process;
extern (C)
{
int daemon(int nochdir, int noclose);
}
void main(string[] args)
{
daemon(0, 0);
auto logFile = File("/Users/gary/Desktop/test.log", "a");
logFile.writeln("Opened file");
string command = format("logger -t %s %s", "Hello", "This is a test.");
executeShell(command); // Crash dump logged at /var/log/system.log
logFile.writeln("Done!"); // Never executes.
}
Comment #4 by andrei — 2013-12-27T14:45:30Z
Gary, is this still failing?
Comment #5 by doob — 2013-12-28T05:33:06Z
(In reply to comment #4)
> Gary, is this still failing?
It's failing for me as well. I don't get a crash but the last line is never printed. It's printed if "executeShell" is not invoked.
Comment #6 by doob — 2013-12-28T05:41:09Z
Doesn't seem to matter what command is passed to "executeShell".
Comment #7 by dlang-bugzilla — 2017-07-21T02:04:10Z
I reproduced it with macOS 10.12 and DMD 2.074.
Changing daemon(0,0) to daemon(0,1) (so that stderr isn't redirected to /dev/null) reveals a clue:
core.thread.ThreadError@src/core/thread.d(3002): Unable to load thread state
It looks like the daemon() call is interfering with Druntime's threading code.
Comment #8 by doob — 2017-07-21T07:10:37Z
(In reply to Vladimir Panteleev from comment #7)
> I reproduced it with macOS 10.12 and DMD 2.074.
>
> Changing daemon(0,0) to daemon(0,1) (so that stderr isn't redirected to
> /dev/null) reveals a clue:
>
> core.thread.ThreadError@src/core/thread.d(3002): Unable to load thread state
>
> It looks like the daemon() call is interfering with Druntime's threading
> code.
I did some more debugging. The error returned by "thread_get_state" is 268435459 (0x10000003) which seems to correspond to MACH_SEND_INVALID_DEST. This bug had the same error code [1]
[1] https://issues.dlang.org/show_bug.cgi?id=6135
Comment #9 by dlang-bugzilla — 2017-07-21T14:52:54Z
(In reply to Jacob Carlborg from comment #8)
> I did some more debugging. The error returned by "thread_get_state" is
> 268435459 (0x10000003) which seems to correspond to MACH_SEND_INVALID_DEST.
Interesting. daemon() calls fork(), and forked processes go on without the other threads from their parent process. It could be that something in Druntime has created a thread, which is now gone after the fork; or, possibly, that the thread ID of the main thread has changed, and Druntime is unable to correctly address it. I'm not familiar with Mach threading, though, so I can only guess.
Comment #10 by pro.mathias.lang — 2020-01-16T13:30:06Z
I cannot reproduce the issue anymore (Mac OSX 10.15.2, DMD 2.090.0). Is it still present ?
Comment #11 by robert.schadek — 2024-12-07T13:32:45Z