Фильтрация нежелательных строк в моментальном снимке кучи версии 8 программно (без графического интерфейса разработчика)

#javascript #node.js #v8

#javascript #node.js #v8

Вопрос:

У меня есть приложение узла, которое отправляет исходный код JavaScript в виде строки рабочему потоку, который выполняет его в API виртуальной машины узла. Я делаю снимок только кучи рабочего потока. Это делается для обнаружения любых выделений строк в исходном коде JavaScript. Однако я получаю много неясных комментариев в виде строк, которые раздувают кучу.

введите описание изображения здесь

Изначально я подозревал, что это связано с тем, как виртуальная машина узла выполняет код в виде строки, поэтому я прокомментировал часть своего кода VM, но я все еще получаю эти нежелательные строки. Возможно, это связано с использованием require() и import ?

Мой код выглядит следующим образом. Опять же, app.js просто передает исходный код в виде строки в мой рабочий поток, worker.mjs . worker.mjs будет запускать переданные строковые данные внутри изолированной среды виртуальной машины, а затем записывать их снимок кучи в файл.

 // App.js file
const { Worker, isMainThread } = require('worker_threads');

if (isMainThread) {
    // JavaScript source code passed as String.
    let workerData = `
    var nop = unescape("%u9090%u9090");
    while (nop.length <= 0x100000/2) {nop  = nop;}`;

    const worker = new Worker('./worker.mjs', { workerData });

    worker.once('message', (filename) => {
      console.log(`worker heapdump: ${filename}`);
    });
  
    // Tell the worker to create a heapdump.
    worker.postMessage('heapdump');
};
  
 // worker.mjs
import { workerData, parentPort, threadId } from 'worker_threads';
import { createContext, runInContext } from 'vm';
import { writeHeapSnapshot, getHeapSnapshot } from 'v8';

parentPort.once('message', (message) => {
    if (message === 'heapdump') {
        const sandbox = {};
        const strict = '"use strict";'

        createContext(sandbox);

        runInContext(strict workerData, sandbox, {timeout: 10000 });

        parentPort.postMessage(writeHeapSnapshot());
    }
});
  

Моя конечная цель — собрать все строки и объединенные строки, созданные только из исходного кода строки workerData . В этом примере значение nop переменной.

введите описание изображения здесь

Но, как показано, в конкатенированной строке также так много пустых данных.

 "encodingOps.ucs2.byteLength"@29509
"encodingOps.utf16le.byteLength"@29531
"encodingOps.latin1.byteLength"@29555
"encodingOps.ascii.byteLength"@29579
"encodingOps.base64.byteLength"@29603
"encodingOps.hex.byteLength"@29627
"module.exports.getModuleFromWrap"@39059
...
...
"internal/modules/package_json_reader.js"@10997
"internal/modules/esm/translators.js"@11001
"internal/modules/esm/transform_source.js"@11011
"internal/modules/esm/resolve.js"@11021
"internal/modules/esm/module_map.js"@11025
"internal/modules/esm/module_job.js"@11029
"internal/modules/esm/loader.js"@11033
"internal/modules/esm/get_source.js"@11043
"internal/modules/esm/get_format.js"
  

Модуль виртуальной машины позволяет компилировать и запускать код в контекстах виртуальной машины версии 8. Модуль виртуальной машины не является механизмом безопасности. Не используйте его для запуска ненадежного кода. https://nodejs.org/api/vm.html

Я понимаю, что виртуальная машина узла выполняет код в своем собственном контексте. Можно ли получить идентификатор контекста виртуальной машины, а затем отфильтровать моментальный снимок кучи для строк, находящихся в этом конкретном контексте? В этом случае мне нужна только nop переменная. Я надеюсь на какой-то способ анализа JSON моментального снимка без использования chrome dev-tools .

Ответ №1:

Возможно, это связано с использованием require() и import ?

По сути, да. Вы хотели все строки, вы получаете все строки. JavaScript использует много строк. (Конкретный механизм импорта не имеет значения. Если вы выполните какой-либо код, вы увидите его строки / etc в моментальном снимке кучи.)

Можно ли получить идентификатор контекста виртуальной машины, а затем отфильтровать моментальный снимок кучи для строк, находящихся в этом конкретном контексте?

Нет, нет никакой связи между объектами кучи и контекстами.