Skip to content
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

29 post process based on bugcheck value #54

Merged
merged 11 commits into from
Jan 26, 2025
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# WebDBG
A React Static Web App (SWA) frontend with a containerized Javascript API backend that injests `.dmp` files and returns analyzed text.

## Analysis
By default `!analyze -v` is executed against each dump and the results are returned. Advanced post-processing can be configured in `/api/post-process.js` in `bugcheckCommands`.

Specify any Bugcheck you want to act up and define the comamnd that should be run against that dump. This app is limited to one additional command per dump, additional commands would require additional logic. Please open an issue if this is required.

## Public Site
This project is hosted publicly on a best effort basis at https://webdbg.rtech.support as a service by the [r/Techsupport Discord Server](https://rtech.support/discord).

Expand Down
20 changes: 13 additions & 7 deletions api/analyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from 'fs';
import path from 'path';
import { exec } from 'child_process';
import winston from 'winston';
import postProcessResults from './post-process.js'; // Corrected import path

// Configure Winston logger
const logger = winston.createLogger({
Expand All @@ -16,11 +17,13 @@ const logger = winston.createLogger({
]
});

// Define the parser
const parser = 'cdb.exe';

// Run the debugger over the dmp file and report errors should failure occur
const processDmpObject = (dmp) => {
return new Promise((resolve) => {
logger.info(`Analysis started on ${dmp}`)
const parser = 'cdb.exe';
const command = `-z ${dmp} -c "k; !analyze -v ; q"`;

exec(`${parser} ${command}`, (error, stdout, stderr) => {
Expand All @@ -37,7 +40,7 @@ const processDmpObject = (dmp) => {
};

// Split the raw content provided by processDmpObject
const processResult = (rawContent) => {
const processResult = (dmp, rawContent) => {
// Splitting the content
let splits = rawContent.split('------------------');
splits = splits.flatMap(split => split.split('STACK_TEXT:'));
Expand All @@ -63,11 +66,11 @@ const processResult = (rawContent) => {

const argMatches = analysis.match(/Arg\d: ([0-9a-fA-Fx]+)/g);
const args = argMatches ? argMatches.map(arg => arg.split(': ')[1]) : [];
logger.info(`Bugcheck: ${bugcheck}`)
logger.info(`Args: ${args}`)
logger.info(`Bugcheck: ${bugcheck}, Args: ${args}`);

// Output object creation
const output = {
dmp: dmp, // Include the dmp file path
dmpInfo: dmpInfo,
analysis: analysis,
bugcheck: bugcheck,
Expand All @@ -86,20 +89,23 @@ const Analyze = async (target) => {
if (!statPath.isDirectory()) {
const dmp = path.resolve(target);
const result = await processDmpObject(dmp);
const processedResult = processResult(result);
const processedResult = processResult(dmp, result);
dmpArray.push(processedResult);
} else { // Run a job for every dmp file found, this drastically reduces processing time
const files = fs.readdirSync(target).filter(file => file.endsWith('.dmp'));
const promises = files.map(async (file) => {
const dmp = path.resolve(target, file);
const result = await processDmpObject(dmp);
return processResult(result);
return processResult(dmp, result);
});
const results = await Promise.all(promises);
dmpArray.push(...results);
}

return JSON.stringify(dmpArray);
// Call the postProcessResults function with the parser
const postProcessedResults = await postProcessResults(dmpArray, parser);

return JSON.stringify(postProcessedResults);
};

export default Analyze;
65 changes: 65 additions & 0 deletions api/post-process.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { exec } from 'child_process';
import winston from 'winston';

// Configure Winston logger
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'post-process.log' })
]
});

// Configuration object for bugcheck commands
const bugcheckCommands = {
'9f': (parser, dmp, args) => `${parser} -z ${dmp} -c "k; !devstack ${args[1]} ; q"`,
// Add more bugcheck commands here as needed
// '<bugcheck>': (dmp, args) => `${parser} -z ${dmp} -c "k; <commands to run> ; q"`,
// Args can be used in a command ${args[#]}
// Arg counts start at 0 so "Arg1" is ${args[0]}
};

// Function to execute a command and return a promise
const executeCommand = (command) => {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(error);
} else if (stderr) {
resolve(`Warnings: ${stderr}`);
} else {
resolve(stdout);
}
});
});
};

// Function to perform additional operations on the analysis results
const postProcessResults = async (results, parser) => {
for (const result of results) {
const commandGenerator = bugcheckCommands[result.bugcheck];
if (commandGenerator) {
const command = commandGenerator(parser, result.dmp, result.args);
logger.info(`Executing command: ${command}`);
try {
const output = await executeCommand(command);
result.post = output;
logger.info('Post-process completed');
} catch (error) {
result.post = error;
logger.error(`An error occured while post-processing the file: ${error}`);
}
} else {
result.post = "No post processing configured for this bugcheck" // Add a null post key if no command is run
logger.info(`No command for bugcheck: ${result.bugcheck}`);
}
}

return results;
};

export default postProcessResults;
1 change: 1 addition & 0 deletions swa/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const FileUpload = () => {
const order = [
"dmpInfo",
"analysis",
"post",
"rawContent",
];
const specialKeys = ["rawContent"];
Expand Down
8 changes: 8 additions & 0 deletions swa/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ body {
.result-header.analysis {
visibility: hidden;
}

.result-header.post::before {
content: "Post Processing";
visibility: visible;
}
.result-header.post {
visibility: hidden;
}
.result-header.dmpInfo::before {
content: "Dump Info";
visibility: visible;
Expand Down
Loading