Description
Hello,
While performing the load testing on my application I've noticed a segfault. My environment and conditions are:
- VPS under OpenVZ, Ubuntu 14.04
- Node v4.0.0
- Using PM2 v0.14.7 (cluster mode, 4 processes in cluster)
- Big application (about 1000+ files, total codebase size ~2MB without node_modules)
- All node_modules are built on current version of Node
- At pm2's config I've set the memory limit of 500 MB per process.
So, under load (about 50-100 rps) when some process runs out of memory, it's killed and restarted by PM2, but sometimes after that the parent PM2 process just fails with "Segmentation fault".
I've researched that for a while (compiled debug version, ran under gdb, etc) and found the source of segfault in src/stream_base-inl.h
:
template <class Base>
void StreamBase::GetFD(Local<String> key,
const PropertyCallbackInfo<Value>& args) {
StreamBase* wrap = Unwrap<Base>(args.Holder());
if (!wrap->IsAlive()) // SEGFAULT.
return args.GetReturnValue().Set(UV_EINVAL);
args.GetReturnValue().Set(wrap->GetFD());
}
I assumed that somehow the wrap
pointer becomes NULL. I didn't research deeper, so I assumed that Unwrap
function failed to do what it's needed for and just returned NULL, but the code of GetFD
didn't handle this correctly. So I tried this small fix:
- if (!wrap->IsAlive())
+ if (!wrap || !wrap->IsAlive())
return args.GetReturnValue().Set(UV_EINVAL);
And it seems to work so far - no single failure for an hour of load testing, and I'm going to leave it working for some days to be sure.
Does this solution seem to be correct? Should I make a PR for it?