diff --git a/.vscode/launch.json b/.vscode/launch.json index 5d4c30e..f2e8c0d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -96,6 +96,19 @@ ], "type": "node" }, + { + "name": "Start: addon:windows", + "request": "launch", + "runtimeArgs": [ + "run-script", + "start:addon:windows", + ], + "runtimeExecutable": "npm", + "skipFiles": [ + "/**" + ], + "type": "node" + }, { "name": "Test", "request": "launch", @@ -109,5 +122,6 @@ ], "type": "node" }, + ] } \ No newline at end of file diff --git a/bin/index.ts b/bin/index.ts index 24e1cbc..7206036 100644 --- a/bin/index.ts +++ b/bin/index.ts @@ -22,6 +22,8 @@ import { argDefinitions, usageDefinitions, } from './command-line-definitions'; +import firstline from 'firstline'; +import type { dumpSyms } from 'node-dump-syms'; (async () => { let { @@ -36,7 +38,7 @@ import { remove, files, directory, - dumpSyms, + dumpSyms: shouldRunDumpSyms, } = await getCommandLineOptions(argDefinitions); if (help) { @@ -110,18 +112,18 @@ import { const globPattern = `${directory}/${files}`; - let symbolFilePaths = await glob(globPattern); + let foundFilePaths = await glob(globPattern); - if (!symbolFilePaths.length) { + if (!foundFilePaths.length) { throw new Error( `Could not find any files to upload using glob ${globPattern}!` ); } - console.log(`Found files:\n ${symbolFilePaths.join('\n')}`); + console.log(`Found files:\n ${foundFilePaths.join('\n')}`); - if (dumpSyms) { - let nodeDumpSyms; + if (shouldRunDumpSyms) { + let nodeDumpSyms: typeof dumpSyms; try { nodeDumpSyms = (await importNodeDumpSyms()).dumpSyms; @@ -132,13 +134,11 @@ import { ); } - symbolFilePaths = symbolFilePaths.map((file) => { - console.log(`Dumping syms for ${file}...`); - const symFile = join(tmpDir, randomUUID(), getNormalizedSymFileName(basename(file))); - mkdirSync(dirname(symFile), { recursive: true }); - nodeDumpSyms(file, symFile); - return symFile; - }); + const newSymFilePaths: Array = []; + + for (const file of foundFilePaths) { + newSymFilePaths.push(await runDumpSyms(nodeDumpSyms, file)); + } } await uploadSymbolFiles( @@ -146,7 +146,7 @@ import { database, application, version, - symbolFilePaths + foundFilePaths ); await safeRemoveTmp(); process.exit(0); @@ -235,6 +235,25 @@ function normalizeDirectory(directory: string): string { return directory.replace(/\\/g, '/'); } +async function runDumpSyms( + nodeDumpSyms: typeof dumpSyms, + inputFilePath: string +) { + console.log(`Dumping syms for ${inputFilePath}...`); + + const uuid = randomUUID(); + const tmpSymFile = join(tmpDir, randomUUID(), `${uuid}.sym`); + + mkdirSync(dirname(tmpSymFile), { recursive: true }); + nodeDumpSyms(inputFilePath, tmpSymFile); + + const symFirstLine = await firstline(tmpSymFile); + const moduleName = 'todo bg'; + const outputFilePath = 'todo bg'; + + return outputFilePath; +} + function validAuthenticationArguments({ user, password, diff --git a/package.json b/package.json index eed7e48..6325b3f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "start:dump_syms": "ts-node -r dotenv/config ./bin/index.ts -d ./spec -f \"**/*.dSYM\" -m", "start:dump_syms_invalid": "ts-node -r dotenv/config ./bin/index.ts -d ./spec -f \"**/myQtCrasher.vc.pdb\" -m", "start:symsrv": "ts-node -r dotenv/config ./bin/index.ts -d ./spec -f \"**/*.dll\"", + "start:addon:windows": "ts-node -r dotenv/config ./bin/index.ts -d ./spec -f \"**/addon-windows.node\" -m", "test": "ts-node node_modules/jasmine/bin/jasmine", "help": "ts-node ./bin/index.ts -h", "clean": "rimraf ./dist", diff --git a/spec/support/addon-macos.node b/spec/support/addon-macos.node new file mode 100755 index 0000000..0e22fda Binary files /dev/null and b/spec/support/addon-macos.node differ diff --git a/spec/support/addon-windows.node b/spec/support/addon-windows.node new file mode 100644 index 0000000..ea26042 Binary files /dev/null and b/spec/support/addon-windows.node differ diff --git a/spec/sym.spec.ts b/spec/sym.spec.ts index 2364b3b..46658a0 100644 --- a/spec/sym.spec.ts +++ b/spec/sym.spec.ts @@ -68,6 +68,14 @@ describe('sym', () => { expect(normalizedSymModuleName).toBe(expected); }); + it('should get normalized sym module name for file with .node extension', () => { + const expected = 'liba.node'; + + const normalizedSymModuleName = getNormalizedSymModuleName('liba.node'); + + expect(normalizedSymModuleName).toBe(expected); + }); + it('should get normalized sym module name for file with .so extension', () => { const expected = 'liba.so'; @@ -126,6 +134,14 @@ describe('sym', () => { expect(normalizedSymFileName).toBe(expected); }); + it('should get normalized sym file name for file with .node extension', () => { + const expected = 'liba.node.sym'; + + const normalizedSymFileName = getNormalizedSymFileName('liba.node'); + + expect(normalizedSymFileName).toBe(expected); + }); + it('should get normalized sym file name for file with .so extension', () => { const expected = 'liba.so.sym'; diff --git a/src/sym.ts b/src/sym.ts index a265ffc..c5c598b 100644 --- a/src/sym.ts +++ b/src/sym.ts @@ -3,7 +3,7 @@ import { basename } from 'node:path'; export async function getSymFileInfo( path: string -): Promise<{ dbgId: string; moduleName: string }> { +): Promise<{ dbgId: string; moduleName: string, fileName: string }> { try { const firstLine = await firstline(path); const matches = Array.from( @@ -38,8 +38,8 @@ export function getNormalizedSymModuleName(moduleName: string): string { } } - // We've seen .pdb, .so, .so.0, and .so.6 in the module lookup, leave them alone - const ignoredExtensions = [/\.pdb$/gm, /\.so\.?.*$/gm, /\.dylib$/gm]; + // We've seen .node, .pdb, .so, .so.0, and .so.6 in the module lookup, leave them alone + const ignoredExtensions = [/\.node$/gm, /\.pdb$/gm, /\.so\.?.*$/gm, /\.dylib$/gm]; if (ignoredExtensions.some((regex) => regex.test(moduleName))) { return moduleName; } @@ -57,7 +57,6 @@ export function getNormalizedSymModuleName(moduleName: string): string { // This is a bit of a mystery and is subject to change when we learn more about how it works. // For now, normalize some sym file names to satisfy the minidump-stackwalker symbol lookup. // When building the path, the pattern is module/GUID/file.sym - export function getNormalizedSymFileName(path: string): string { let normalizedFileName = basename(path); @@ -69,8 +68,8 @@ export function getNormalizedSymFileName(path: string): string { } } - // We've seen .dylib.sym, .so.sym, .so.0.sym, and .so.6.sym in the sym file lookup, leave them alone - const ignoredExtensions = [/\.dylib$/gm, /\.so\.?.*$/gm]; + // We've seen .node.sym, .dylib.sym, .so.sym, .so.0.sym, and .so.6.sym in the sym file lookup, leave them alone + const ignoredExtensions = [/\.node$/gm, /\.dylib$/gm, /\.so\.?.*$/gm]; if (ignoredExtensions.some((regex) => regex.test(normalizedFileName))) { return `${normalizedFileName}.sym`; }