-
-
Notifications
You must be signed in to change notification settings - Fork 34.2k
src,lib: support path in v8.writeHeapSnapshot output
#58959
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
base: main
Are you sure you want to change the base?
Conversation
v8.writeHeapSnapshot output
dfc2f3a to
3ef78c4
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #58959 +/- ##
==========================================
- Coverage 88.54% 88.51% -0.03%
==========================================
Files 703 703
Lines 208545 208569 +24
Branches 40216 40240 +24
==========================================
- Hits 184652 184625 -27
- Misses 15905 15954 +49
- Partials 7988 7990 +2
🚀 New features to boost your workflow:
|
jasnell
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BufferValue uses need to be cleaned up
b956356 to
0055948
Compare
|
@addaleax @jasnell @Renegade334 PTAL :-) |
src/heap_utils.cc
Outdated
| if (WriteSnapshot(env, final_filename.c_str(), options).IsNothing()) return; | ||
|
|
||
| args.GetReturnValue().Set( | ||
| String::NewFromUtf8(isolate, final_filename.c_str()).ToLocalChecked()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this is going to be a problem because it assumes the final_filename is utf8 encoded. Consider the following case:
const path = Buffer.from([0xe6]); // latin 1 character
fs.mkdirSync(path);
const res = v8.writeHeapSnapshot(undefined, { path });
fs.readfileSync(res); // fails! path doesn't existThe reason fs.readfileSync would fail here is because the returned res will have interpreted the 0xe6 character incorrectly and will have replaced it with the unicode replacement char. The snapshot will have been written to disk correctly, but the returned path is wrong.
This likely needs to return the resulting path as a Buffer if the path was given as a Buffer and allow the API to accept an encoding option that optionally decodes the result as a string. But, that gets a bit awkward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love how picky this is, aaah, let me put the encoding option to make this a bit more consistent and leave utf8 as default encoding.
Nice catch, thanks! Anything else missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing that sticks out, but I should have time to take another pass through by end of day monday
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey James, I know its been a while; I've been quite busy lately, but now I have some bandwidth...
James, your snippet won't work.
node:fs:1326
const result = binding.mkdir(
^
Error: EILSEQ: illegal byte sequence, mkdir '�'
at Object.mkdirSync (node:fs:1326:26)
at Object.<anonymous> (/private/tmp/case.js:5:4)
at Module._compile (node:internal/modules/cjs/loader:1759:14)
at Object..js (node:internal/modules/cjs/loader:1890:10)
at Module.load (node:internal/modules/cjs/loader:1480:32)
at Module._load (node:internal/modules/cjs/loader:1299:12)
at TracingChannel.traceSync (node:diagnostics_channel:328:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:245:24)
at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
at node:internal/main/run_main_module:33:47 {
errno: -92,
code: 'EILSEQ',
syscall: 'mkdir',
path: '�'
}
I'm not able to create a latin1 folder in Node.js. I get the encoding requirements and stuff... but your snippet per se is not valid. What would you like me to do in this case? What should I consider adding in the test case?
juanarbol
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm gonna use StringBytes::Encode but I would like to get my question answered before doing something
src/heap_utils.cc
Outdated
| if (WriteSnapshot(env, final_filename.c_str(), options).IsNothing()) return; | ||
|
|
||
| args.GetReturnValue().Set( | ||
| String::NewFromUtf8(isolate, final_filename.c_str()).ToLocalChecked()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey James, I know its been a while; I've been quite busy lately, but now I have some bandwidth...
James, your snippet won't work.
node:fs:1326
const result = binding.mkdir(
^
Error: EILSEQ: illegal byte sequence, mkdir '�'
at Object.mkdirSync (node:fs:1326:26)
at Object.<anonymous> (/private/tmp/case.js:5:4)
at Module._compile (node:internal/modules/cjs/loader:1759:14)
at Object..js (node:internal/modules/cjs/loader:1890:10)
at Module.load (node:internal/modules/cjs/loader:1480:32)
at Module._load (node:internal/modules/cjs/loader:1299:12)
at TracingChannel.traceSync (node:diagnostics_channel:328:14)
at wrapModuleLoad (node:internal/modules/cjs/loader:245:24)
at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
at node:internal/main/run_main_module:33:47 {
errno: -92,
code: 'EILSEQ',
syscall: 'mkdir',
path: '�'
}
I'm not able to create a latin1 folder in Node.js. I get the encoding requirements and stuff... but your snippet per se is not valid. What would you like me to do in this case? What should I consider adding in the test case?
0055948 to
ff92f3d
Compare
|
@jasnell PTAL |
|
Fixing linter and CI, sorry. |
ff92f3d to
641975c
Compare
Fixes: nodejs#58857 Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
641975c to
070a019
Compare
| if (StringBytes::Encode(isolate, final_filename.c_str(), encoding) | ||
| .ToLocal(&ret)) { | ||
| args.GetReturnValue().Set(ret); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with the position of this StringBytes operation is that if it fails, the function call will throw but will still have had meaningful side-effects. It would probably be better to attempt the encoding before snapshotting.
| const encoding = options?.encoding || 'utf8'; | ||
| return triggerHeapSnapshot(filename, optionArray, options?.path, encoding); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Defaulting this here shouldn't be necessary; ParseEncoding will fall back to the provided default if the value is undefined or not a string.
| const encoding = options?.encoding || 'utf8'; | |
| return triggerHeapSnapshot(filename, optionArray, options?.path, encoding); | |
| return triggerHeapSnapshot(filename, optionArray, options?.path, options?.encoding); |
| filename = getValidatedPath(filename); | ||
| } | ||
|
|
||
| if (options?.path !== undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I believe the general convention for options validation is to check for any nullish value, unless null has a discrete meaning for that option.
| if (options?.path !== undefined) { | |
| if (options?.path != undefined) { |
I'm a bit rusty with my C++. Any feedback will be more than valuable.