bun
bun copied to clipboard
Segmentation fault with EJS running under Mitata for benchmarking
Version
0.1.4
Platform
Linux davidpc 5.15.0-41-generic #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
What steps will reproduce the bug?
I have a simple benchmark running EJS that causes Bun to do a segmentation fault. The benchmark is using Mitata just as the Bun benchmarks do. Commenting out all EJS code lets the benchmark run okay. The benchmark runs correctly on Node.js. And running the same EJS code but not with Mitata it runs correctly on Bun.
import { bench, run } from "mitata";
import * as ejs from 'ejs';
let people = ['geddy', 'neil', 'alex'];
bench('literal', () => { return `${people.join(', ')}`; });
bench('ejs-join', () => {
ejs.render('<%= people.join(", "); %>', { people: people });
});
try {
await run();
} catch (err) { console.error(err); }
When executed -- of course you must install mitata and ejs -- I get this output:
SegmentationFault at 24
–––– bun meta ––––
Bun v0.1.4 Linux x64 #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022
AutoCommand:
Elapsed: 27ms | User: 25ms | Sys: 4ms
RSS: 67.11MB | Peak: 32.12MB | Commit: 67.11MB | Faults: 0
–––– bun meta ––––
Ask for #help in https://bun.sh/discord or go to https://bun.sh/issues
Commenting out the bench invocation for ejs-join it still segfaults. Commenting out the import for EJS and it runs correctly.
$ bun render.mjs
cpu: Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz
runtime: bun 0.1.4 (x64-linux)
benchmark time (avg) (min … max) p75 p99 p995
------------------------------------------------- -----------------------------
literal 136.1 ns/iter (108.35 ns … 395.06 ns) 136.37 ns 307 ns 314.28 ns
Then, if I use this code (the same EJS invocation but no Mitata)
import * as ejs from 'ejs';
let people = ['geddy', 'neil', 'alex'];
console.log(ejs.render('<%= people.join(", "); %>', {people: people}));
Bun executes it correctly:
$ bun rendering.mjs
geddy, neil, alex
How often does it reproduce? Is there a required condition?
Every time
What is the expected behavior?
Expected behavior is for the benchmark to run correctly
What do you see instead?
The segfaults discussed above.
Additional information
Both Mitata and EJS are the latest versions (3.1.8 for EJS)
I'm trying several template engines to try a comparison. So far Liquid and Handlebars both execute correctly on Bun, but Nunjucks has a similar issue.
// NUNJUCKS
import nunjucks from 'nunjucks';
bench('nunjucks-join', () => {
const output = nunjucks.renderString('{{ people | join(", ") }}', { people: people });
// console.log(output);
});
bench(`nunjucks-list`, () => {
const output = nunjucks.renderString(`
<ul id="products">
{% for person in people %}
<li>{{ person }}</li>
{% endfor %}
</ul>
`, { people: people });
// console.log(output);
});
This also causes a segfault which is only cured when commenting out the import for nunjucks
Running Nunjucks outside of Mitata with this code:
let people = ['geddy', 'neil', 'alex'];
import nunjucks from 'nunjucks';
const output = nunjucks.renderString('{{ people | join(", ") }}', { people: people });
console.log(output);
Gives this error:
20 | _inheritsLoose(FileSystemLoader, _Loader);
21 |
22 | function FileSystemLoader(searchPaths, opts) {
23 | var _this;
24 |
25 | _this = _Loader.call(this) || this;
^
TypeError: _Loader.call is not a function. (In '_Loader.call(this)', '_Loader.call' is undefined)
at new FileSystemLoader (/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/src/node-loaders.js:25:12)
at configure (/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/index.js:41:21)
at renderString (/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/index.js:96:6)
at /home/david/Projects/akasharender/akashacms-perftest/adhoc/rendering.mjs:10:15
Next up is MarkdownIT ... similar story. Running it in the context of Mitata causes a segmentation fault. Running it on its own executes correctly.
import { promises as fsp } from 'fs';
import MarkdownIt from 'markdown-it';
const mditConfig = {
html: true, // Enable html tags in source
xhtmlOut: true, // Use '/' to close single tags (<br />)
breaks: false, // Convert '\n' in paragraphs into <br>
// langPrefix: 'language-', // CSS language prefix for fenced blocks
linkify: true, // Autoconvert url-like texts to links
typographer: false, // Enable smartypants and other sweet transforms
// Highlighter function. Should return escaped html,
// or '' if input not changed
highlight: function (/*str, , lang*/) { return ''; }
};
const md = MarkdownIt(mditConfig);
// const doc1 = await fsp.readFile('fixtures/document.md', 'utf-8');
const doc1 = `
# Title 1
Some text [with a link](http://somewhere.com)
## Title 2
* Person 1
* Person 2
* Person 3
`;
bench('markdown-render', () => {
const output = md.render(doc1);
// console.log(output);
});
The behavior is the same whether read from a file, or an inline constant.
$ bun render-bun.js
SegmentationFault at 24
–––– bun meta ––––
Bun v0.1.4 Linux x64 #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022
AutoCommand:
Elapsed: 158ms | User: 114ms | Sys: 16ms
RSS: 67.11MB | Peak: 57.90MB | Commit: 67.11MB | Faults: 0
–––– bun meta ––––
And run without Mitata it executes correctly
import MarkdownIt from 'markdown-it';
const mditConfig = {
html: true, // Enable html tags in source
xhtmlOut: true, // Use '/' to close single tags (<br />)
breaks: false, // Convert '\n' in paragraphs into <br>
// langPrefix: 'language-', // CSS language prefix for fenced blocks
linkify: true, // Autoconvert url-like texts to links
typographer: false, // Enable smartypants and other sweet transforms
// Highlighter function. Should return escaped html,
// or '' if input not changed
highlight: function (/*str, , lang*/) { return ''; }
};
const md = MarkdownIt(mditConfig);
// const doc1 = await fsp.readFile('fixtures/document.md', 'utf-8');
const doc1 = `
# Title 1
Some text [with a link](http://somewhere.com)
## Title 2
* Person 1
* Person 2
* Person 3
`;
const output = md.render(doc1);
console.log(output);
I'm unable to reproduce this on an M1, but I am able to reproduce this on Linux x64
These failures happen with the Canary build of Bun 0.1.5
With Bun 0.1.8 on Linux/x86 I now get this result -- no segfaults on the engines that had failed earlier -- but there's an issue with Nunjucks that I have not investigated yet.
> [email protected] render:bun
> bun render-bun.js
cpu: Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz
runtime: bun 0.1.8 (x64-linux)
benchmark time (avg) (min … max)
------------------------------------------------------------
literal 138.63 ns/iter (113.11 ns … 589.08 ns)
ejs-join 24.47 µs/iter (16.8 µs … 3.59 ms)
ejs-list 44.79 µs/iter (31.96 µs … 2.98 ms)
handlebars-join-once 4.21 µs/iter (2.94 µs … 2.44 ms)
handlebars-list-once 4.5 µs/iter (3.33 µs … 772.88 µs)
liquid-join 39.59 µs/iter (21.56 µs … 2.84 ms)
liquid-list 124.14 µs/iter (81.42 µs … 1.62 ms)
nunjucks-join error: _Loader.call is not a function. (In '_Loader.call(this)', '_Loader.call' is undefined)
FileSystemLoader@/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/src/node-loaders.js:31:27
configure@/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/index.js:31:52
renderString@/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/index.js:76:18
@/home/david/Projects/akasharender/akashacms-perftest/bench/render-bun.js:62:39
@/home/david/Projects/akasharender/akashacms-perftest/node_modules/mitata/src/lib.mjs:37:19
@/home/david/Projects/akasharender/akashacms-perftest/node_modules/mitata/src/cli.mjs:188:40
@[native code]
nunjucks-list error: _Loader.call is not a function. (In '_Loader.call(this)', '_Loader.call' is undefined)
FileSystemLoader@/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/src/node-loaders.js:31:27
configure@/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/index.js:31:52
renderString@/home/david/Projects/akasharender/akashacms-perftest/node_modules/nunjucks/index.js:76:18
@/home/david/Projects/akasharender/akashacms-perftest/bench/render-bun.js:65:39
@/home/david/Projects/akasharender/akashacms-perftest/node_modules/mitata/src/lib.mjs:37:19
@/home/david/Projects/akasharender/akashacms-perftest/node_modules/mitata/src/cli.mjs:188:40
@[native code]
markdown-render 37.61 µs/iter (21.89 µs … 5.59 ms)
cheerio 94.1 µs/iter (55.77 µs … 3.53 ms)
BTW -Following is the same test running on Node.js. The primary performance difference is with Cheerio.
> [email protected] render:node
> node render-node.mjs
cpu: Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz
runtime: node v18.6.0 (x64-linux)
benchmark time (avg) (min … max)
-------------------------------------------------------
literal 137.42 ns/iter (119.7 ns … 495.03 ns)
ejs-join 17.66 µs/iter (13.9 µs … 832.51 µs)
ejs-list 30.77 µs/iter (25.41 µs … 612.14 µs)
handlebars-join 6.19 µs/iter (4.82 µs … 665.49 µs)
handlebars-list 6.46 µs/iter (5.07 µs … 494.04 µs)
liquid-join 30.37 µs/iter (16.69 µs … 4.29 ms)
liquid-list 95.18 µs/iter (60.39 µs … 1.65 ms)
nunjucks-join 46.9 µs/iter (25.24 µs … 3.39 ms)
nunjucks-list 91.13 µs/iter (62.01 µs … 1.66 ms)
markdown-render 38.42 µs/iter (27.24 µs … 807.91 µs)
cheerio 154.99 µs/iter (87.67 µs … 5.14 ms)
Thank you for trying again and posting results
That _Loader.call
issue is interesting, either an issue with bun's node polyfills or a CommonJS transform bug - closing this since the original issue is fixed. Please open an issue for the nunjucks-list bug