-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FreeBSD daemonize Node.js fails with crash while boot time #2411
Comments
Can you check other Node.js versions as well (in particular, latest v13.x and latest v12.x)? Is there any other output, and/or can you share the Node.js binary you’re using so that one can correlate the stack trace to source code positions? My best guess is that the issue is that Node.js finds that the stdio fds are missing and that opening |
Unfortunately I am not able to test the newest versions, but I've tested 12.13.1 but with the same results. Here is my code in file "start.js": "use strict";
console.log(__dirname);
console.log("start.js")
const cluster = require('cluster');
const fs = require("fs");
const errlog = fs.createWriteStream(__dirname + "/error.log", {flags: "a"});
if (cluster.isMaster) {
//Master-Process
errlog.write("master\n", "utf8")
errlog.write("fork\n", "utf8")
cluster.fork();
cluster.on("error", (info) => {
errlog.write(`Error: ${info}\n`, "utf8")
});
cluster.on("exit", (code, signal) => {
//cluster.fork();
errlog.write(`Exit: ${JSON.stringify(code)} ${signal}\n`, "utf8");
});
} else {
//Sub-Process
errlog.write("worker\n", "utf8")
console.log("lade server")
errlog.write("starte server\n", "utf8")
const server = require("./web.js");
console.log("starte listening für server")
errlog.write("starte listening für server\n", "utf8")
server.listen(3080);
} And "web.js": "use strict";
const http = require("http");
const fs = require("fs");
const zlib = require("zlib");
const errlog = fs.createWriteStream(__dirname + "/error.log", {flags: "a"});
errlog.write("web.js\n", "utf8")
//Pfad-Parser
const urlPathParse = (str) => {
const qstart = str.indexOf("?");
const hstart = str.indexOf("#");
const len = str.length;
const obj = {
filePath: str.slice(str.indexOf("/"), qstart !== -1 ? qstart : (hstart !== -1 ? hstart : len)),
hash: hstart !== -1 ? str.slice(hstart+1, len) : ""
}
const fpPos = obj.filePath.lastIndexOf("/");
obj.file = obj.filePath.slice(fpPos + 1);
obj.path = obj.filePath.slice(0, fpPos + 1);
const fdPos = obj.file.indexOf(".");
obj.fileExt = fdPos !== -1 ? obj.file.slice(fdPos + 1) : "";
if (qstart !== -1) {
const queryStr = str.slice(qstart + 1, hstart !== -1 ? hstart : len);
if (queryStr !== "") {
const arr = queryStr.split("&");
const qobj = {};
for (let i = 0, l = arr.length; i < l; i++) {
const ePos = arr[i].indexOf("=");
const al = arr[i].length;
const sep = ePos !== -1 ? ePos : al;
const tmp = [arr[i].slice(0,sep),arr[i].slice(sep+1, al)];
if (tmp[0] === "") continue;
qobj[tmp[0]] = tmp[1];
}
obj.query = qobj;
} else obj.query = {};
} else obj.query = {};
return obj;
}
String.prototype.contains = function(str) {
"use strict";
return this.indexOf(str) !== -1;
}
const webdir = __dirname + "/web";
console.log("komprimiere dateien")
errlog.write("komprimiere dateien\n", "utf8")
//Erstelle vorkomprimierte Daten in einen Cache
const fileCache = {};
(() => {
const files = fs.readdirSync(webdir);
files.forEach(fileR => {
const file = webdir + "/" + fileR;
if(!fs.statSync(file).isFile()) return;
if (file.contains(".gz") || file.contains(".br")) return;
const fileBuf = fs.readFileSync(file, {encoding: "utf8"});
const mtimeMs = fs.statSync(file).mtimeMs;
fileCache[file] = {buf: fileBuf};
fileCache[file].size = Buffer.byteLength(fileCache[file].buf);
fileCache[file].mtimeMs = mtimeMs;
fileCache[file + ".gzip"] = {buf: zlib.gzipSync(fileBuf, {level: zlib.constants.Z_BEST_COMPRESSION})};
fileCache[file + ".gzip"].size = Buffer.byteLength(fileCache[file + ".gzip"].buf);
fileCache[file + ".gzip"].mtimeMs = mtimeMs;
fileCache[file + ".br"] = {buf: zlib.brotliCompressSync(fileBuf, {BROTLI_PARAM_MODE: "BROTLI_MODE_TEXT", BROTLI_PARAM_QUALITY: "BROTLI_MAX_QUALITY"})};
fileCache[file + ".br"].size = Buffer.byteLength(fileCache[file + ".br"].buf);
fileCache[file + ".br"].mtimeMs = mtimeMs;
});
})();
console.log("öffne streams für logfiles")
errlog.write("öffne streams für logfiles\n", "utf8")
//Datei für Log
const logfile = fs.createWriteStream(__dirname + "/logfile.log", {flags: "a"});
//mime-Types
const mime = {
"html": "text/html",
"js": "text/javascript",
"css": "text/css",
"woff2": "font/woff2"
};
//Webserver
const server = http.createServer((req, res) => {
const time = Date.now();
const url = urlPathParse(req.url);
//Konvertiere url-Daten zu Index-Seite
if (url.filePath === "/") {
url.filePath = "/index.html";
url.file = "index.html";
url.fileExt = "html";
}
const fullPath = webdir + url.filePath;
if (fileCache[fullPath]) {
if (fileCache[fullPath].mtimeMs == req.headers["if-none-match"]) {
res.writeHead(304);
res.end();
} else {
//Prüfe akzeptierte Kompressionsmethode und streame Datei mit voher versandten passendem Header
let compr = "";
if (req.headers['accept-encoding'].contains("br")) {
compr = "br";
} else if (req.headers['accept-encoding'].contains("gzip")) {
compr = "gzip";
}
const comprPath = compr ? "." + compr : "";
//const statSize = compr ? (await fs.promises.stat(fullPath + comprPath)).size : stat.size;
//const statSize = compr ? fileCache[fullPath + comprPath].byteLength : stat.size;
const statSize = compr ? fileCache[fullPath + comprPath].size : fileCache[fullPath].size;
res.writeHead(200, {
'Content-Type': mime[url.fileExt] + "; charset=utf-8",
'Cache-Control': 'max-age=' + (url.fileExt === "html" ? '0' : '900'),
'Content-Length': statSize,
//'ETag': stat.mtimeMs,
'ETag': fileCache[fullPath].mtimeMs,
'Content-Encoding': compr
});
//fs.createReadStream(fullPath + comprPath).pipe(res);
res.end(fileCache[fullPath + comprPath].buf);
}
};
//Wenn sonst nix passt, Error oder Weiterleitung
if (!res.headersSent) {
if (url.fileExt) {
res.statusCode = 404;
res.end("Stille Leere");
} else {
res.writeHead(301, {
'location': req.headers.host + "/"
});
res.end();
}
}
logfile.write(`${time};${req.method};${req.url};${res.statusCode};${req.headers.referer};"${req.headers['user-agent']}"\n`, "utf8");
});
server.on('clientError', (err, socket) => {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
//server.listen(8080);
module.exports = server;
process.on("error", (info) => {
errlog.write("Error: "+info+"\n", "utf8")
}); This results in the following stout-messages: /www/miniserver
start.js
1: 0x15ddb80 node::Abort(void) [/usr/local/bin/node]
2: 0x15b56ca node::PlatformInit(void) [/usr/local/bin/node]
3: 0x15b4bf4 node::InitializeOncePerProcess(int, char**) [/usr/local/bin/node]
4: 0x15b503e node::Start(int, char**) [/usr/local/bin/node] And "error.log" contains: master
fork
Exit: {"_events":{},"_eventsCount":1,"exitedAfterDisconnect":false,"state":"dead","id":1,"process":{"_events":{"internalMessage":[null,null]},"_eventsCount":3,"_closesNeeded":2,"_closesGot":1,"connected":false,"signalCode":"SIGABRT","exitCode":null,"killed":false,"spawnfile":"/usr/local/bin/node","_handle":null,"spawnargs":["/usr/local/bin/node","/www/miniserver/start.js"],"pid":30386,"stdin":null,"stdout":null,"stderr":null,"stdio":[null,null,null,null],"channel":null,"_handleQueue":null,"_pendingMessage":null}} null |
Ok, after further testing I realized its not the require of custom modules, which is problematic. I just used a relative path, which I've corrected, but the real error is still using |
Any indication as to why |
No, there's no solution yet. Now I've tested it with Node 13.7
|
I have the same issue, but I am not using cluster. If you want the node binary, it's here : http://pkg.freebsd.org/FreeBSD:12:amd64/quarterly/All/node-13.10.1_1.txz |
Would it be possible for either of you to check what line in https://github.com/nodejs/node/blob/3e2a3007107b7a100794f4e4adbde19263fc7464/src/node.cc#L571-L688 |
I mange to have the core dump Edit; I think I understand the issue. When we use daemon witt -o or -S, stdin is something, and this generate the abort. The workaround I have found : |
I can't (meaningfully) read the core dump on my system but can you check locally with gdb or lldb what the |
Thank you Kal42. The workaround solves the problem. |
@Zabrah - is this still outstanding? looks like this issue can be closed now .please let me know if that is not the case. |
@PoojaDurgad - Yes, it can be closed. |
A simple solution to this is to pass the |
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases (e.g. /dev/null could already have been opened by the acting process and not actually be mapped to the expected file descriptor); instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Refs: nodejs#875 Fixes: nodejs/help#2411
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases (e.g. /dev/null could already have been opened by the acting process and not actually be mapped to the expected file descriptor); instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: nodejs#875
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases (e.g. /dev/null could already have been opened by the acting process and not actually be mapped to the expected file descriptor); instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: nodejs#875
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases (e.g. /dev/null could already have been opened by the acting process and not actually be mapped to the expected file descriptor); instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: nodejs#875
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases (e.g. /dev/null could already have been opened by the acting process and not actually be mapped to the expected file descriptor); instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: nodejs#875
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases (e.g. /dev/null could already have been opened by the acting process and not actually be mapped to the expected file descriptor); instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: nodejs#875
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases (e.g. /dev/null could already have been opened by the acting process and not actually be mapped to the expected file descriptor); instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: nodejs#875
When checking for the validity of the stdio file descriptors (nodejs#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: nodejs#875
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
When checking for the validity of the stdio file descriptors (#875), ones which don't exist are intended to be remapped to /dev/null (and, if that doesn't work, we abort). This however doesn't work on all platforms and in all cases, and is not anymore required by POSIX; instead, use the `dup2` syscall as a more robust solution (conforms to POSIX.1). Fixes: nodejs/help#2411 Refs: #875 PR-URL: #44461 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Hi,
I am trying to get a Node.js app to run via an rc.d script in FreeBSD. While the OS runtime the rc.d script works fine and my app starts as expected.
But on system boot Node crashes. I didn't get enough info, so I traced the issue by logging some code-positions into a file via write-stream.
With this info Node.js seems to crash every time it comes to
cluster.fork
, but I cannot be 100% sure.Could there be any dependency, that have to be waited for, before Node can safely be started while booting FreeBSD?
Here's the code of my rc.d script, with already some dependencies I thought they would be enough.
I already searched the net for example startup scripts, but every of them are for using with the modules forever or pm2. But I want to try to get it working without them.
The only info coming from the daemon-service into the daemon.log is this (not even console.log infos are redirected into that file):
The text was updated successfully, but these errors were encountered: