parent
f570ed1b1a
commit
b331b94217
|
@ -35,52 +35,6 @@ export function isExpandable(value: string): number {
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import * as os from "os";
|
import * as os from "os";
|
||||||
|
|
||||||
const filePath = os.homedir() + '/logs.txt';
|
|
||||||
|
|
||||||
|
|
||||||
const userHomeDir = os.homedir();
|
|
||||||
const logQueue = []; // 日志队列
|
|
||||||
let isWriting = false; // 是否正在写入日志
|
|
||||||
|
|
||||||
function writeLogToFile(log, filePath) {
|
|
||||||
return new Promise<void>((resolve, reject) => {
|
|
||||||
fs.appendFile(filePath, log + '\n', (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function processLogQueue() {
|
|
||||||
if (logQueue.length === 0 || isWriting) {
|
|
||||||
return; // 如果队列为空或正在写入日志,则不进行处理
|
|
||||||
}
|
|
||||||
|
|
||||||
isWriting = true; // 设置正在写入日志的标志
|
|
||||||
|
|
||||||
const { log, filePath } = logQueue.shift(); // 从队列中取出第一个日志
|
|
||||||
|
|
||||||
writeLogToFile(log, filePath)
|
|
||||||
.then(() => {
|
|
||||||
console.log('日志已成功写入文件:', filePath);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error('无法写入日志文件:', err);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
isWriting = false; // 写入完成后,将正在写入日志的标志设置为false
|
|
||||||
processLogQueue(); // 继续处理队列中的下一个日志
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addToLogQueue(log, filePath) {
|
|
||||||
return;
|
|
||||||
logQueue.push({ log, filePath }); // 将日志添加到队列中
|
|
||||||
processLogQueue(); // 开始处理队列中的日志
|
|
||||||
}
|
|
||||||
|
|
||||||
function isJSON(str) {
|
function isJSON(str) {
|
||||||
var jList = [];
|
var jList = [];
|
||||||
|
@ -98,8 +52,6 @@ function writeLogToFile(log, filePath) {
|
||||||
|
|
||||||
|
|
||||||
export function expandValue(variableCreate: Function, value: string, root: string = "", extra: any = undefined): any {
|
export function expandValue(variableCreate: Function, value: string, root: string = "", extra: any = undefined): any {
|
||||||
addToLogQueue("debug.output::expandValue=====xxxx1", filePath);
|
|
||||||
addToLogQueue(`debug.output::expandValue=====xxxx2 ${value}: ${JSON.stringify(extra)}`, filePath);
|
|
||||||
|
|
||||||
let jsonVar = false;
|
let jsonVar = false;
|
||||||
if(value.indexOf("=")!=-1){
|
if(value.indexOf("=")!=-1){
|
||||||
|
@ -165,9 +117,6 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
|
|
||||||
//解析字典,json
|
//解析字典,json
|
||||||
const parseTupleOrList = () => {
|
const parseTupleOrList = () => {
|
||||||
|
|
||||||
addToLogQueue(`debug.output::parseTupleOrList=====xxxx10 ${value}`, filePath);
|
|
||||||
|
|
||||||
value = value.trim();
|
value = value.trim();
|
||||||
if (value[0] != '{')
|
if (value[0] != '{')
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -192,7 +141,6 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
const newValPos1 = value.indexOf("{");
|
const newValPos1 = value.indexOf("{");
|
||||||
const newValPos2 = value.indexOf(",");
|
const newValPos2 = value.indexOf(",");
|
||||||
let newValPos = newValPos1;
|
let newValPos = newValPos1;
|
||||||
addToLogQueue(`debug.output::parseTupleOrList=====xxxx10 ${value}:${eqPos}: ${newValPos}: ${newValPos2}`, filePath);
|
|
||||||
|
|
||||||
if (newValPos2 != -1 && newValPos2 < newValPos1){
|
if (newValPos2 != -1 && newValPos2 < newValPos1){
|
||||||
newValPos = newValPos2;
|
newValPos = newValPos2;
|
||||||
|
@ -246,8 +194,6 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
};
|
};
|
||||||
|
|
||||||
const parsePrimitive = () => {
|
const parsePrimitive = () => {
|
||||||
addToLogQueue(`debug.output::parsePrimitive=====xxxx20 ${value}`, filePath);
|
|
||||||
|
|
||||||
let primitive: any;
|
let primitive: any;
|
||||||
let match;
|
let match;
|
||||||
value = value.trim();
|
value = value.trim();
|
||||||
|
@ -296,7 +242,9 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
|
|
||||||
parseValue = () => {
|
parseValue = () => {
|
||||||
value = value.trim();
|
value = value.trim();
|
||||||
addToLogQueue(`debug.output::parseValue=====xxxx3 ${value}`, filePath);
|
// if(value[0] == ','){
|
||||||
|
// value = value.substr(1).trim();
|
||||||
|
// }
|
||||||
|
|
||||||
if (value[0] == '"'){ //解析字符串
|
if (value[0] == '"'){ //解析字符串
|
||||||
return parseCString();
|
return parseCString();
|
||||||
|
@ -305,10 +253,13 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
return parseTupleOrList();
|
return parseTupleOrList();
|
||||||
}
|
}
|
||||||
else if(value.startsWith("std::vector of length")){
|
else if(value.startsWith("std::vector of length")){
|
||||||
addToLogQueue(`debug.output::parseValue=====xxxx4 ${value}`, filePath);
|
|
||||||
const eqPos = value.indexOf("=");
|
const eqPos = value.indexOf("=");
|
||||||
value = value.substr(eqPos).trim();
|
value = value.substr(eqPos+1).trim();
|
||||||
addToLogQueue(`debug.output::parseValue=====xxxx5 ${value}`, filePath);
|
return parseValue();
|
||||||
|
}
|
||||||
|
else if(value.startsWith("std::tuple containing")){
|
||||||
|
const eqPos = value.indexOf("=");
|
||||||
|
value = value.substr(eqPos+1).trim();
|
||||||
return parseValue();
|
return parseValue();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
@ -317,8 +268,6 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
};
|
};
|
||||||
|
|
||||||
parseResult = (pushToStack: boolean = false) => {
|
parseResult = (pushToStack: boolean = false) => {
|
||||||
addToLogQueue(`debug.output::parseResult=====xxxx30 ${value}`, filePath);
|
|
||||||
|
|
||||||
value = value.trim();
|
value = value.trim();
|
||||||
const variableMatch = resultRegex.exec(value);
|
const variableMatch = resultRegex.exec(value);
|
||||||
if (!variableMatch)
|
if (!variableMatch)
|
||||||
|
@ -346,7 +295,6 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
createValue = (name, val) => {
|
createValue = (name, val) => {
|
||||||
let ref = 0;
|
let ref = 0;
|
||||||
let evaluateName;
|
let evaluateName;
|
||||||
addToLogQueue(`debug.output::parseResult=====xxxx40 ${value}`, filePath);
|
|
||||||
|
|
||||||
if (typeof val == "object") {
|
if (typeof val == "object") {
|
||||||
ref = variableCreate(val);
|
ref = variableCreate(val);
|
||||||
|
@ -374,21 +322,21 @@ export function expandValue(variableCreate: Function, value: string, root: strin
|
||||||
evaluateName = getNamespace(name);
|
evaluateName = getNamespace(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
value = value.trim();
|
// value = value.trim();
|
||||||
if (value[0] == ',')
|
// if (value[0] == ',')
|
||||||
{
|
// {
|
||||||
var tmp = value
|
// var tmp = value
|
||||||
tmp = tmp.substr(1).trim();
|
// tmp = tmp.substr(1).trim();
|
||||||
tmp = tmp.trim();
|
// tmp = tmp.trim();
|
||||||
if(tmp[0] == '{' && jsonVar == true){
|
// if(tmp[0] == '{' && jsonVar == true){
|
||||||
tmp = ",anonymous union = " + tmp;
|
// tmp = ",anonymous union = " + tmp;
|
||||||
value = tmp;
|
// value = tmp;
|
||||||
}
|
// }
|
||||||
else if(tmp.startsWith("<No data fields>")){
|
// else if(tmp.startsWith("<No data fields>")){
|
||||||
value = tmp = tmp.substr("<No data fields>".length);
|
// value = tmp = tmp.substr("<No data fields>".length);
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: name,
|
name: name,
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
var os = require('os');
|
||||||
|
|
||||||
|
const MAX_LOG_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||||
|
const MAX_LOG_FILES = 7;
|
||||||
|
|
||||||
|
const LOG_LEVEL = {
|
||||||
|
DEBUG: 'DEBUG',
|
||||||
|
INFO: 'INFO',
|
||||||
|
WARNING: 'WARNING',
|
||||||
|
ERROR: 'ERROR'
|
||||||
|
};
|
||||||
|
|
||||||
|
let SETLOGLEVEL = LOG_LEVEL.DEBUG;
|
||||||
|
let localPath = `${os.homedir()}/.debug`;
|
||||||
|
fs.mkdirSync(localPath, { recursive: true });
|
||||||
|
|
||||||
|
const logFilePath = path.join(localPath, 'log_1.txt');
|
||||||
|
|
||||||
|
// 输出通道
|
||||||
|
function initializeLogFile() {
|
||||||
|
try {
|
||||||
|
// Check if log directory exists
|
||||||
|
if (!fs.existsSync(localPath)) {
|
||||||
|
fs.mkdirSync(localPath, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all existing log files
|
||||||
|
const existingLogs = fs.readdirSync(localPath).filter((file: string) => file.startsWith('log_') && file.endsWith('.txt'));
|
||||||
|
|
||||||
|
// Remove excess log files if needed
|
||||||
|
while (existingLogs.length >= MAX_LOG_FILES) {
|
||||||
|
const oldestLogFile = getOldestLogFile(existingLogs);
|
||||||
|
const filePath = path.join(localPath, oldestLogFile);
|
||||||
|
fs.unlinkSync(filePath);
|
||||||
|
console.info(`Removed old log file: ${oldestLogFile}`);
|
||||||
|
existingLogs.splice(existingLogs.indexOf(oldestLogFile), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new log file if it doesn't exist or if the current one exceeds the size limit
|
||||||
|
if (!fs.existsSync(logFilePath) || fs.statSync(logFilePath).size > MAX_LOG_SIZE) {
|
||||||
|
rotateLogFiles();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to initialize log file:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOldestLogFile(logFiles: string | any[]) {
|
||||||
|
let oldestFile = logFiles[0];
|
||||||
|
let oldestFileCreationTime = fs.statSync(path.join(localPath, oldestFile)).birthtime;
|
||||||
|
for (let i = 1; i < logFiles.length; i++) {
|
||||||
|
const file = logFiles[i];
|
||||||
|
const fileCreationTime = fs.statSync(path.join(localPath, file)).birthtime;
|
||||||
|
if (fileCreationTime < oldestFileCreationTime) {
|
||||||
|
oldestFile = file;
|
||||||
|
oldestFileCreationTime = fileCreationTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return oldestFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
function rotateLogFiles() {
|
||||||
|
try {
|
||||||
|
// Rename existing log files with incremented numbers
|
||||||
|
for (let i = MAX_LOG_FILES - 1; i > 0; i--) {
|
||||||
|
const sourceFilePath = path.join(localPath, `log_${i}.txt`);
|
||||||
|
const destinationFilePath = path.join(localPath, `log_${i + 1}.txt`);
|
||||||
|
if (fs.existsSync(sourceFilePath)) {
|
||||||
|
fs.renameSync(sourceFilePath, destinationFilePath);
|
||||||
|
console.info(`Renamed log file ${sourceFilePath} to ${destinationFilePath}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new log file
|
||||||
|
fs.writeFileSync(logFilePath, '');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to rotate log files:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化日志文件
|
||||||
|
initializeLogFile();
|
||||||
|
|
||||||
|
// 日志输出函数
|
||||||
|
function log(level: string, message: any) {
|
||||||
|
const timestamp = new Date().toISOString();
|
||||||
|
const logMessage = `[${timestamp}] [${level}] ${message}`;
|
||||||
|
if (getLogLevelValue(level) >= getLogLevelValue(SETLOGLEVEL)) {
|
||||||
|
fs.appendFileSync(logFilePath, logMessage + '\n');
|
||||||
|
if (fs.statSync(logFilePath).size > MAX_LOG_SIZE) {
|
||||||
|
rotateLogFiles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录调试级别的日志
|
||||||
|
function debug(message: any) {
|
||||||
|
log(LOG_LEVEL.DEBUG, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录信息级别的日志
|
||||||
|
function info(message: any) {
|
||||||
|
log(LOG_LEVEL.INFO, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录警告级别的日志
|
||||||
|
function warning(message: any) {
|
||||||
|
log(LOG_LEVEL.WARNING, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录错误级别的日志
|
||||||
|
function error(message: any) {
|
||||||
|
log(LOG_LEVEL.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLogLevelValue(level: string) {
|
||||||
|
return Object.keys(LOG_LEVEL).indexOf(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
debug,
|
||||||
|
info,
|
||||||
|
warning,
|
||||||
|
error,
|
||||||
|
LOG_LEVEL,
|
||||||
|
SETLOGLEVEL
|
||||||
|
};
|
|
@ -971,7 +971,6 @@ export class MI2 extends EventEmitter implements IBackend {
|
||||||
async getStackVariables(thread: number, frame: number): Promise<Variable[]> {
|
async getStackVariables(thread: number, frame: number): Promise<Variable[]> {
|
||||||
if (trace)
|
if (trace)
|
||||||
this.log("stderr", "getStackVariables");
|
this.log("stderr", "getStackVariables");
|
||||||
|
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
if (this.status == 'stopped') {
|
if (this.status == 'stopped') {
|
||||||
this.currentThreadId = thread;
|
this.currentThreadId = thread;
|
||||||
|
|
|
@ -23,7 +23,6 @@ const STACK_HANDLES_START = 1000;
|
||||||
const VAR_HANDLES_START = 512 * 256 + 1000;
|
const VAR_HANDLES_START = 512 * 256 + 1000;
|
||||||
const VARIABLES_TAG_REGISTER = 0xab;
|
const VARIABLES_TAG_REGISTER = 0xab;
|
||||||
|
|
||||||
|
|
||||||
export class MI2DebugSession extends DebugSession {
|
export class MI2DebugSession extends DebugSession {
|
||||||
protected variableHandles = new Handles<string | VariableObject | ExtendedVariable>(VAR_HANDLES_START);
|
protected variableHandles = new Handles<string | VariableObject | ExtendedVariable>(VAR_HANDLES_START);
|
||||||
protected variableHandlesReverse: { [id: string]: number } = {};
|
protected variableHandlesReverse: { [id: string]: number } = {};
|
||||||
|
@ -510,16 +509,19 @@ export class MI2DebugSession extends DebugSession {
|
||||||
}
|
}
|
||||||
return varObj.isCompound() ? id : 0;
|
return varObj.isCompound() ? id : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (typeof id == "number") {
|
if (typeof id == "number") {
|
||||||
let stack: Variable[];
|
let stack: Variable[];
|
||||||
try {
|
try {
|
||||||
const [threadId, level] = this.frameIdToThreadAndLevel(id);
|
const [threadId, level] = this.frameIdToThreadAndLevel(id);
|
||||||
stack = await this.miDebugger.getStackVariables(threadId, level);
|
stack = await this.miDebugger.getStackVariables(threadId, level);
|
||||||
|
|
||||||
for (const variable of stack) {
|
for (const variable of stack) {
|
||||||
if (this.useVarObjects) {
|
if (this.useVarObjects) {
|
||||||
try {
|
try {
|
||||||
const varObjName = `var_${id}_${variable.name}`;
|
const varObjName = `var_${id}_${variable.name}`;
|
||||||
let varObj: VariableObject;
|
let varObj: VariableObject;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const changes = await this.miDebugger.varUpdate(varObjName);
|
const changes = await this.miDebugger.varUpdate(varObjName);
|
||||||
const changelist = changes.result("changelist");
|
const changelist = changes.result("changelist");
|
||||||
|
@ -551,6 +553,7 @@ export class MI2DebugSession extends DebugSession {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (variable.valueStr !== undefined) {
|
if (variable.valueStr !== undefined) {
|
||||||
|
|
||||||
let expanded = expandValue(createVariable, `{${variable.name}=${variable.valueStr})`, "", variable.raw);
|
let expanded = expandValue(createVariable, `{${variable.name}=${variable.valueStr})`, "", variable.raw);
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
if (typeof expanded[0] == "string")
|
if (typeof expanded[0] == "string")
|
||||||
|
@ -588,8 +591,10 @@ export class MI2DebugSession extends DebugSession {
|
||||||
// TODO: this evals on an (effectively) unknown thread for multithreaded programs.
|
// TODO: this evals on an (effectively) unknown thread for multithreaded programs.
|
||||||
variable = await this.miDebugger.evalExpression(JSON.stringify(id), 0, 0);
|
variable = await this.miDebugger.evalExpression(JSON.stringify(id), 0, 0);
|
||||||
try {
|
try {
|
||||||
|
|
||||||
let variableValue = variable.result("value");
|
let variableValue = variable.result("value");
|
||||||
// 过滤掉 "\\000 <repeats x times>" 部分
|
// 过滤掉 "\\000 <repeats x times>" 部分
|
||||||
|
|
||||||
variableValue = variableValue.replace(/ '\\000' <repeats \d+ times>,/g, "");
|
variableValue = variableValue.replace(/ '\\000' <repeats \d+ times>,/g, "");
|
||||||
let expanded = expandValue(createVariable, variableValue, id, variable);
|
let expanded = expandValue(createVariable, variableValue, id, variable);
|
||||||
if (!expanded) {
|
if (!expanded) {
|
||||||
|
|
Loading…
Reference in New Issue