Skip to content

Commit

Permalink
Workaround segfault with old glibc versions (parcel-bundler#7457)
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett authored and bhovhannes committed Dec 23, 2021
1 parent 51ddeab commit 356e530
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/transformers/js/package.json
Expand Up @@ -34,6 +34,7 @@
"@parcel/plugin": "^2.0.1",
"@parcel/source-map": "^2.0.0",
"@parcel/utils": "^2.0.1",
"@parcel/workers": "^2.0.1",
"@swc/helpers": "^0.2.11",
"browserslist": "^4.6.6",
"detect-libc": "^1.0.3",
Expand Down
26 changes: 26 additions & 0 deletions packages/transformers/js/src/JSTransformer.js
Expand Up @@ -12,6 +12,7 @@ import nullthrows from 'nullthrows';
import ThrowableDiagnostic, {encodeJSONKeyComponent} from '@parcel/diagnostic';
import {validateSchema, remapSourceLocation} from '@parcel/utils';
import {isMatch} from 'micromatch';
import WorkerFarm from '@parcel/workers';

const JSX_EXTENSIONS = {
jsx: true,
Expand Down Expand Up @@ -278,6 +279,7 @@ export default (new Transformer({
asset.getBuffer(),
asset.getMap(),
init,
loadOnMainThreadIfNeeded(),
]);

let targets;
Expand Down Expand Up @@ -840,3 +842,27 @@ export default (new Transformer({
return [asset];
},
}): Transformer);

// On linux with older versions of glibc (e.g. CentOS 7), we encounter a segmentation fault
// when worker threads exit due to thread local variables used by SWC. A workaround is to
// also load the native module on the main thread, so that it is not unloaded until process exit.
// See https://github.com/rust-lang/rust/issues/91979.
let isLoadedOnMainThread = false;
async function loadOnMainThreadIfNeeded() {
if (
!isLoadedOnMainThread &&
process.platform === 'linux' &&
WorkerFarm.isWorker()
) {
let {family, version} = require('detect-libc');
if (family === 'glibc' && parseFloat(version) <= 2.17) {
let api = WorkerFarm.getWorkerApi();
await api.callMaster({
location: __dirname + '/loadNative.js',
args: [],
});

isLoadedOnMainThread = true;
}
}
}
6 changes: 6 additions & 0 deletions packages/transformers/js/src/loadNative.js
@@ -0,0 +1,6 @@
// This function is called from the main thread to prevent unloading the module
// until the main thread exits. This avoids a segfault in older glibc versions.
// See https://github.com/rust-lang/rust/issues/91979
module.exports = () => {
require('../native');
};

0 comments on commit 356e530

Please sign in to comment.