Skip to content

Commit b8a0cf9

Browse files
29 post process based on bugcheck value (#54)
* comman gets run waypoint * command gets run waypoint * waypoint: post process is sent * add post value to output * add comments for adding new bugcheck commands * waypoint: parser is defined in analyze now * waypoint: updated logging * Finish post-process functionality and notes * update output for no bugcheck * update readme with details on what commands are run on a dump and how to add more * improve error for DS
1 parent 45f7d1e commit b8a0cf9

File tree

5 files changed

+92
-7
lines changed

5 files changed

+92
-7
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# WebDBG
22
A React Static Web App (SWA) frontend with a containerized Javascript API backend that injests `.dmp` files and returns analyzed text.
33

4+
## Analysis
5+
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`.
6+
7+
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.
8+
49
## Public Site
510
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).
611

api/analyze.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from 'fs';
22
import path from 'path';
33
import { exec } from 'child_process';
44
import winston from 'winston';
5+
import postProcessResults from './post-process.js'; // Corrected import path
56

67
// Configure Winston logger
78
const logger = winston.createLogger({
@@ -16,11 +17,13 @@ const logger = winston.createLogger({
1617
]
1718
});
1819

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

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

3942
// Split the raw content provided by processDmpObject
40-
const processResult = (rawContent) => {
43+
const processResult = (dmp, rawContent) => {
4144
// Splitting the content
4245
let splits = rawContent.split('------------------');
4346
splits = splits.flatMap(split => split.split('STACK_TEXT:'));
@@ -63,11 +66,11 @@ const processResult = (rawContent) => {
6366

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

6971
// Output object creation
7072
const output = {
73+
dmp: dmp, // Include the dmp file path
7174
dmpInfo: dmpInfo,
7275
analysis: analysis,
7376
bugcheck: bugcheck,
@@ -86,20 +89,23 @@ const Analyze = async (target) => {
8689
if (!statPath.isDirectory()) {
8790
const dmp = path.resolve(target);
8891
const result = await processDmpObject(dmp);
89-
const processedResult = processResult(result);
92+
const processedResult = processResult(dmp, result);
9093
dmpArray.push(processedResult);
9194
} else { // Run a job for every dmp file found, this drastically reduces processing time
9295
const files = fs.readdirSync(target).filter(file => file.endsWith('.dmp'));
9396
const promises = files.map(async (file) => {
9497
const dmp = path.resolve(target, file);
9598
const result = await processDmpObject(dmp);
96-
return processResult(result);
99+
return processResult(dmp, result);
97100
});
98101
const results = await Promise.all(promises);
99102
dmpArray.push(...results);
100103
}
101104

102-
return JSON.stringify(dmpArray);
105+
// Call the postProcessResults function with the parser
106+
const postProcessedResults = await postProcessResults(dmpArray, parser);
107+
108+
return JSON.stringify(postProcessedResults);
103109
};
104110

105111
export default Analyze;

api/post-process.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { exec } from 'child_process';
2+
import winston from 'winston';
3+
4+
// Configure Winston logger
5+
const logger = winston.createLogger({
6+
level: 'info',
7+
format: winston.format.combine(
8+
winston.format.timestamp(),
9+
winston.format.json()
10+
),
11+
transports: [
12+
new winston.transports.Console(),
13+
new winston.transports.File({ filename: 'post-process.log' })
14+
]
15+
});
16+
17+
// Configuration object for bugcheck commands
18+
const bugcheckCommands = {
19+
'9f': (parser, dmp, args) => `${parser} -z ${dmp} -c "k; !devstack ${args[1]} ; q"`,
20+
// Add more bugcheck commands here as needed
21+
// '<bugcheck>': (dmp, args) => `${parser} -z ${dmp} -c "k; <commands to run> ; q"`,
22+
// Args can be used in a command ${args[#]}
23+
// Arg counts start at 0 so "Arg1" is ${args[0]}
24+
};
25+
26+
// Function to execute a command and return a promise
27+
const executeCommand = (command) => {
28+
return new Promise((resolve, reject) => {
29+
exec(command, (error, stdout, stderr) => {
30+
if (error) {
31+
reject(error);
32+
} else if (stderr) {
33+
resolve(`Warnings: ${stderr}`);
34+
} else {
35+
resolve(stdout);
36+
}
37+
});
38+
});
39+
};
40+
41+
// Function to perform additional operations on the analysis results
42+
const postProcessResults = async (results, parser) => {
43+
for (const result of results) {
44+
const commandGenerator = bugcheckCommands[result.bugcheck];
45+
if (commandGenerator) {
46+
const command = commandGenerator(parser, result.dmp, result.args);
47+
logger.info(`Executing command: ${command}`);
48+
try {
49+
const output = await executeCommand(command);
50+
result.post = output;
51+
logger.info('Post-process completed');
52+
} catch (error) {
53+
result.post = error;
54+
logger.error(`An error occured while post-processing the file: ${error}`);
55+
}
56+
} else {
57+
result.post = "No post processing configured for this bugcheck" // Add a null post key if no command is run
58+
logger.info(`No command for bugcheck: ${result.bugcheck}`);
59+
}
60+
}
61+
62+
return results;
63+
};
64+
65+
export default postProcessResults;

swa/src/App.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ const FileUpload = () => {
116116
const order = [
117117
"dmpInfo",
118118
"analysis",
119+
"post",
119120
"rawContent",
120121
];
121122
const specialKeys = ["rawContent"];

swa/src/style.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ body {
5656
.result-header.analysis {
5757
visibility: hidden;
5858
}
59+
60+
.result-header.post::before {
61+
content: "Post Processing";
62+
visibility: visible;
63+
}
64+
.result-header.post {
65+
visibility: hidden;
66+
}
5967
.result-header.dmpInfo::before {
6068
content: "Dump Info";
6169
visibility: visible;

0 commit comments

Comments
 (0)