修改一些bug
This commit is contained in:
parent
b253ff688f
commit
c679cb81ee
|
@ -16,6 +16,11 @@ deadlock-detect 是一款基于OpenKylin社区kylin-code的拓展插件,用于
|
|||
- 远程环境进程死锁检测
|
||||
|
||||
## 使用方法
|
||||
#### 检查依赖
|
||||
依赖binutils、libc-bin、sshpass软件包
|
||||
安装方式```sudo apt install binutils libc-bin sshpass -y```
|
||||
内核版本在4.19以上,支持BPF,内核选项```CONFIG_BPF_EVENTS=y```
|
||||
|
||||
#### C/C++ 多线程序锁分析
|
||||
* 打开目标C/C++工程,点击`终端`->`配置任务` 选择`deadlockdetect: 可执行程序锁检测`
|
||||
task.json文件中自动添加的锁检测任务如下:
|
||||
|
|
|
@ -206,8 +206,10 @@ class CustomBuildTaskTerminal implements vscode.Pseudoterminal {
|
|||
this.checkedPid = parseInt(result[3].trim());
|
||||
execDetect(this.passwd, result[1].trim(), this.checkedPid, (detectResult)=>{
|
||||
if(detectResult.match(/fatal/)?.length){
|
||||
vscode.window.showWarningMessage("被检测程序存在严重问题!")
|
||||
kill(this.checkedPid, 9);
|
||||
vscode.window.showWarningMessage("被检测程序存在严重问题!");
|
||||
}else if(detectResult.match(/deadlock/)?.length){
|
||||
kill(this.checkedPid, 9);
|
||||
vscode.window.showWarningMessage("被检测程序存在死锁!");
|
||||
}
|
||||
if(detectResult.match(/normal|fatal|deadlock/)?.length){
|
||||
|
@ -219,7 +221,7 @@ class CustomBuildTaskTerminal implements vscode.Pseudoterminal {
|
|||
enableScripts: true,
|
||||
retainContextWhenHidden: true,
|
||||
}
|
||||
)
|
||||
);
|
||||
webPanel.webview.html = prase_yaml2html(this.command, this.context.extensionPath, webPanel.webview, detectResult);
|
||||
}else{
|
||||
vscode.window.showInformationMessage("程序已退出,但未检测到相关锁信息");
|
||||
|
|
|
@ -5,7 +5,8 @@ import path = require('path');
|
|||
import fs = require("fs");
|
||||
import {DetectTaskProvider} from './detectTaskProvider';
|
||||
import { homedir } from 'os';
|
||||
|
||||
import {exec} from 'child_process';
|
||||
import {testPwd} from './utils';
|
||||
// linux命令操作模块
|
||||
var child = require('child_process');
|
||||
const { pid } = require('process');
|
||||
|
@ -26,23 +27,6 @@ function getWebViewContent(context: vscode.ExtensionContext, templatePath: strin
|
|||
return html;
|
||||
}
|
||||
|
||||
function is_pid_exist(pid: string) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
child.exec(`ps -ef`, (e: any, x: string, c: any) => {
|
||||
if(e){
|
||||
reject('ps命令执行错误!')
|
||||
}else{
|
||||
let search=new RegExp("\\s+"+pid+"\\s+");
|
||||
let exist=search.test(x);
|
||||
if(exist){
|
||||
resolve('1');
|
||||
}else{
|
||||
resolve('-1');
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
// this method is called when your extension is activated
|
||||
// your extension is activated the very first time the command is executed
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
|
@ -50,39 +34,18 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
// Use the console to output diagnostic information (console.log) and errors (console.error)
|
||||
// This line of code will only be executed once when your extension is activated
|
||||
console.log('Congratulations, your extension "deadlock-detect" is now active!');
|
||||
|
||||
let newFn={
|
||||
local_detect_deadlock:function (message: any ,panel: vscode.WebviewPanel){
|
||||
let form=message.form;
|
||||
|
||||
if(form.CmdType==1){
|
||||
|
||||
child.exec(`echo '${form.pwd}' | sudo -S ps`, (e: any, x: string, c: any) => {
|
||||
if(e){
|
||||
form.success='error-pwd';
|
||||
form.msg='您输入的密码错误!';
|
||||
if(e.message.indexOf('sudoers')!=-1){
|
||||
form.msg='当前用户无sudo权限,请在拥有sudo权限后重试!';
|
||||
}
|
||||
panel.webview.postMessage({
|
||||
res: form
|
||||
})
|
||||
if(form.CmdType===1){
|
||||
testPwd(form.pwd, (ok)=>{
|
||||
if(!ok){
|
||||
vscode.window.showErrorMessage("用户密码不匹配");
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
let pid_exist = is_pid_exist(form.pid);
|
||||
pid_exist.then((result)=>{
|
||||
console.log(result);
|
||||
if(result=='-1'){
|
||||
form.success='error-pid';
|
||||
form.msg='进程号不存在,请重新输入';
|
||||
panel.webview.postMessage({
|
||||
res: form
|
||||
})
|
||||
return
|
||||
}else if(result=='1'){
|
||||
child.exec(`echo '${form.pwd}' | sudo -S ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.pid}`, (e: any, x: string, c: any) => {
|
||||
if(fs.existsSync(`/proc/${form.pid}`))
|
||||
{
|
||||
exec(`echo '${form.pwd}' | sudo -S ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.pid}`, (e: any, x: string, c: string) => {
|
||||
// console.log(`echo '${form.pwd}' | sudo ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.pid}`);
|
||||
if(!e){
|
||||
form.data =x;
|
||||
|
@ -96,106 +59,60 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
res: form});
|
||||
}
|
||||
});
|
||||
}else{
|
||||
vscode.window.showErrorMessage(`当前不存在${form.pid}进程`);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
remote_detect_deadlock:function (message: any ,panel: vscode.WebviewPanel){
|
||||
let form=message.form;
|
||||
|
||||
if(form.CmdType==3){
|
||||
if(form.CmdType===3){
|
||||
// sudo apt install sshpass
|
||||
child.exec(`sshpass -p '${form.pwd}' ssh -o StrictHostKeyChecking=no ${form.user}@${form.ip}`, (e: any, x: string, c: any) => {
|
||||
exec(`sshpass -p '${form.pwd}' ssh -o StrictHostKeyChecking=no ${form.user}@${form.ip} 'echo "${form.pwd}" | sudo -S ls /proc/${form.pid}'`, (e: any, x: string, c: string) => {
|
||||
if(e){
|
||||
form.success='error-ssh-login';
|
||||
form.msg='无法登录您指定的远端系统,请确保具有ssh登录权限!';
|
||||
panel.webview.postMessage({
|
||||
res: form
|
||||
})
|
||||
return;
|
||||
}
|
||||
})
|
||||
child.exec(`sshpass -p '${form.pwd}' ssh -o StrictHostKeyChecking=no ${form.user}@${form.ip} 'echo "${form.pwd}" | sudo -S ps'`, (e: any, x: string, c: any) => {
|
||||
if(e){
|
||||
form.success='error-not-sudoer';
|
||||
form.msg='user is not sudoer!';
|
||||
if(e.message.indexOf('sudoers')!=-1){
|
||||
form.msg='当前用户无sudo权限,请在拥有sudo权限后重试!';
|
||||
}
|
||||
panel.webview.postMessage({
|
||||
res: form
|
||||
})
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
let pid_exist = new Promise(function(resolve, reject) {
|
||||
child.exec(`sshpass -p '${form.pwd}' ssh -o StrictHostKeyChecking=no ${form.user}@${form.ip} 'echo "${form.pwd}" | sudo -S ps -ef'`, (e: any, x: string, c: any) => {
|
||||
if(e){
|
||||
reject('ps命令执行错误!')
|
||||
if(c.includes('Permission denied')){
|
||||
vscode.window.showErrorMessage("远程主机用户名或密码错误");
|
||||
}else if(c.includes('ls:')){
|
||||
vscode.window.showErrorMessage(`远程主机不存在${form.pid}进程`);
|
||||
}else{
|
||||
let search=new RegExp("\\s+"+form.pid+"\\s+");
|
||||
let exist=search.test(x);
|
||||
if(exist){
|
||||
resolve('1');
|
||||
}else{
|
||||
resolve('-1');
|
||||
}
|
||||
vscode.window.showErrorMessage(`远程主机无法路由,或其他未知错误`);
|
||||
}
|
||||
})
|
||||
});
|
||||
pid_exist.then((result)=>{
|
||||
console.log(result);
|
||||
if(result=='-1'){
|
||||
form.success='error-pid';
|
||||
form.msg='进程号不存在,请重新输入';
|
||||
panel.webview.postMessage({
|
||||
res: form
|
||||
})
|
||||
return;
|
||||
}else if(result=='1'){
|
||||
child.exec(`sshpass -p '${form.pwd}' ssh -o StrictHostKeyChecking=no ${form.user}@${form.ip} '[ ! -d .deadlock-detect ] && mkdir .deadlock-detect || ls .deadlock-detect'`, (e: any, x: string, c: any) => {
|
||||
// console.log(`echo '${form.pwd}' | sudo ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.pid}`);
|
||||
if(e){
|
||||
form.success='error-mkdir';
|
||||
form.msg='创建目录.deadlock-detect失败!';
|
||||
panel.webview.postMessage({
|
||||
res: form});
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
child.exec(`sshpass -p '${form.pwd}' ssh -o StrictHostKeyChecking=no ${form.user}@${form.ip} '[ ! -d .deadlock-detect ] && mkdir .deadlock-detect || ls .deadlock-detect'`, (e: any, x: string, c: any) => {
|
||||
// console.log(`echo '${form.pwd}' | sudo ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.pid}`);
|
||||
if(e){
|
||||
vscode.window.showErrorMessage("远程主机无法创建目录, 请确认登录用户是否拥有权限.");
|
||||
return;
|
||||
}
|
||||
child.exec(`sshpass -p '${form.pwd}' scp -o StrictHostKeyChecking=no ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.user}@${form.ip}:./.deadlock-detect`, (e: any, x: string, c: any) => {
|
||||
// console.log(`echo '${form.pwd}' | sudo ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.pid}`);
|
||||
if(e){
|
||||
form.success='error-scp';
|
||||
form.msg='scp EXE failed!';
|
||||
panel.webview.postMessage({
|
||||
res: form});
|
||||
vscode.window.showErrorMessage("远程主机无法拷贝文件, 请确认登录用户是否拥有权限.");
|
||||
return;
|
||||
}
|
||||
child.exec(`sshpass -p '${form.pwd}' ssh -o StrictHostKeyChecking=no ${form.user}@${form.ip} 'echo "${form.pwd}" | sudo -S ./.deadlock-detect/detect_deadlock ${form.pid}'`, (e: any, x: string, c: any) => {
|
||||
// console.log(`echo '${form.pwd}' | sudo ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.pid}`);
|
||||
if(!e){
|
||||
form.data =x;
|
||||
form.success='success';
|
||||
panel.webview.postMessage({
|
||||
res: form});
|
||||
}
|
||||
else{
|
||||
form.success='error';
|
||||
panel.webview.postMessage({
|
||||
res: form});
|
||||
}
|
||||
});
|
||||
});
|
||||
child.exec(`sshpass -p '${form.pwd}' ssh -o StrictHostKeyChecking=no ${form.user}@${form.ip} 'echo "${form.pwd}" | sudo -S ./.deadlock-detect/detect_deadlock ${form.pid}'`, (e: any, x: string, c: any) => {
|
||||
// console.log(`echo '${form.pwd}' | sudo ${__dirname}/../detect-tools/x86_64/detect_deadlock ${form.pid}`);
|
||||
if(!e){
|
||||
form.data =x;
|
||||
console.log(x);
|
||||
form.success='success';
|
||||
panel.webview.postMessage({
|
||||
res: form});
|
||||
}
|
||||
else{
|
||||
form.success='error';
|
||||
panel.webview.postMessage({
|
||||
res: form});
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
// The command has been defined in the package.json file
|
||||
// Now provide the implementation of the command with registerCommand
|
||||
// The commandId parameter must match the command field in package.json
|
||||
|
@ -224,9 +141,26 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
});
|
||||
panel.webview.html = getWebViewContent(context, 'dist/index.html');
|
||||
});
|
||||
|
||||
const workspaceRoot = (vscode.workspace.workspaceFolders && (vscode.workspace.workspaceFolders.length > 0)) ? vscode.workspace.workspaceFolders[0].uri.fsPath : homedir();
|
||||
detectTaskProvider = vscode.tasks.registerTaskProvider(DetectTaskProvider.customBuildScriptType, new DetectTaskProvider(workspaceRoot, context));
|
||||
exec(`which sshpass`, (e, o, err)=>{
|
||||
if(e){
|
||||
vscode.window.showWarningMessage('当前环境缺失sshpass工具,C/C++程序远程死锁检测功能受限,请执行 sudo apt install sshpass 安装.');
|
||||
return;
|
||||
}
|
||||
});
|
||||
exec(`uname -r`, (e, o, err)=>{
|
||||
if(e){
|
||||
vscode.window.showWarningMessage("检测环境失败, C/C++程序锁分析插件功能受限");
|
||||
return;
|
||||
}
|
||||
exec(`grep -r "^CONFIG_BPF_EVENTS=" /boot/config-${o}`, (e1, o1, err1)=>{
|
||||
if(e1){
|
||||
vscode.window.showWarningMessage("由于内核限制, C/C++程序锁分析插件功能受限");
|
||||
return;
|
||||
}
|
||||
const workspaceRoot = (vscode.workspace.workspaceFolders && (vscode.workspace.workspaceFolders.length > 0)) ? vscode.workspace.workspaceFolders[0].uri.fsPath : homedir();
|
||||
detectTaskProvider = vscode.tasks.registerTaskProvider(DetectTaskProvider.customBuildScriptType, new DetectTaskProvider(workspaceRoot, context));
|
||||
});
|
||||
});
|
||||
context.subscriptions.push(disposable);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ function circledNodesPosition(x:number, y: number, index: number, nodesLen: numb
|
|||
return {
|
||||
x: Math.sin((ahd * index)) * 15 + x,
|
||||
y: Math.cos((ahd * index)) * 15 + y
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// warn: "process exit"
|
||||
|
@ -119,7 +119,7 @@ function product_deadlockinfo_to_html(cmd: string, echartsPath: string, deadlock
|
|||
type: 'graph',
|
||||
layout: 'none',
|
||||
roam: true,
|
||||
symbolSize: 80,
|
||||
symbolSize: 70,
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
|
@ -129,7 +129,7 @@ function product_deadlockinfo_to_html(cmd: string, echartsPath: string, deadlock
|
|||
normal: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
fontSize: 8
|
||||
fontSize: 14
|
||||
},
|
||||
formatter: "{c}"
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ function product_deadlockinfo_to_html(cmd: string, echartsPath: string, deadlock
|
|||
lineStyle: {
|
||||
opacity: 0.9,
|
||||
width: 2,
|
||||
curveness: -0.1
|
||||
curveness: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -151,7 +151,7 @@ function product_deadlockinfo_to_html(cmd: string, echartsPath: string, deadlock
|
|||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
`;
|
||||
}
|
||||
|
||||
// 输入正常锁信息的html
|
||||
|
@ -211,7 +211,7 @@ function product_normalinfo_to_html(cmd: string, echartsPath: string, mutexInfo:
|
|||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
`;
|
||||
}
|
||||
|
||||
// 线程退出但是未释放锁
|
||||
|
@ -241,7 +241,7 @@ function product_fatalinfo_to_html(cmd: string, fatalInfo:string) {
|
|||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
`;
|
||||
}
|
||||
|
||||
// 发生死锁
|
||||
|
@ -306,27 +306,27 @@ function parse_mutexInfo(mutexObj:MutexInfo[], sinfoList:SourceInfo[], dimension
|
|||
<li>
|
||||
进入互斥量(${key})保护的临界区 ${info[0]} 次, 共耗时 ${info[1]} 纳秒, 条件变量等待 ${info[2]} 纳秒.
|
||||
</li>
|
||||
`
|
||||
`;
|
||||
}else{
|
||||
miStr += `
|
||||
<li>
|
||||
进入互斥量(${key})保护的临界区 ${info[0]} 次, 共耗时 ${info[1]} 纳秒.
|
||||
</li>
|
||||
`
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
miStr += `
|
||||
</ul>
|
||||
</li>
|
||||
`
|
||||
`;
|
||||
sinfoList.push(sinfo);
|
||||
});
|
||||
dimensionsList.push('product');
|
||||
mutexSet.forEach((mutex)=>{
|
||||
dimensionsList.push(mutex);
|
||||
});
|
||||
for (let index = 0; index < sinfoList.length; index++) {
|
||||
for (let index = 0; index < dimensionsList.length-1; index++) {
|
||||
seriesList.push({type:'bar'});
|
||||
}
|
||||
return miStr;
|
||||
|
@ -387,7 +387,7 @@ function parse_deadlockInfo(dlInfo:DeadlockInfo, dataList: object[], linksList:
|
|||
target: (index+1)%dlInfo.cycle.length,
|
||||
value: `线程 ${value}`,
|
||||
lineStyle: {
|
||||
curveness: 0.2
|
||||
curveness: -0.2
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<el-button type="primary" v-on:click="begin_local_check()">开始检测</el-button>
|
||||
</div>
|
||||
<br />
|
||||
<el-card v-loading="loading" element-loading-text="正在检测..." class="box-card" style="width: 80%;margin: auto;">
|
||||
<el-card class="box-card" style="width: 80%;margin: auto;">
|
||||
<div slot="header" class="clearfix" v-if="loading == false">
|
||||
<span>{{ local_thread_data }}</span>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue