add check process with pid
This commit is contained in:
parent
5bc1030004
commit
09c4c89216
|
@ -4,6 +4,16 @@ ARCH=`arch`
|
||||||
DIR=`dirname $0`
|
DIR=`dirname $0`
|
||||||
BINLOADER=$DIR/${ARCH}/binloader
|
BINLOADER=$DIR/${ARCH}/binloader
|
||||||
|
|
||||||
|
if [ -n "`ps -ef | grep deadlockcheck | grep -v grep`" ];then
|
||||||
|
exit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
SUPPORTBPF=`grep -r "^CONFIG_BPF_EVENTS=" /boot/config-$(uname -r)`
|
||||||
|
if [ -z "$SUPPORTBPF" ];then
|
||||||
|
echo "Current Kernel not support ebpf"
|
||||||
|
exit 100
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $# -lt 1 ];then
|
if [ $# -lt 1 ];then
|
||||||
# echo "Error params"
|
# echo "Error params"
|
||||||
exit 101
|
exit 101
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
#!/usr/bin/bash
|
||||||
|
ARCH=`arch`
|
||||||
|
|
||||||
|
DIR=`dirname $0`
|
||||||
|
CHECKTOOL=$DIR/${ARCH}/deadlockcheck
|
||||||
|
|
||||||
|
if [ -n "`ps -ef | grep deadlockcheck | grep -v grep`" ];then
|
||||||
|
exit 99
|
||||||
|
fi
|
||||||
|
|
||||||
|
SUPPORTBPF=`grep -r "^CONFIG_BPF_EVENTS=" /boot/config-$(uname -r)`
|
||||||
|
if [ -z "$SUPPORTBPF" ];then
|
||||||
|
echo "Current Kernel not support ebpf"
|
||||||
|
exit 100
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $# -lt 1 ];then
|
||||||
|
# echo "Error params"
|
||||||
|
exit 101
|
||||||
|
fi
|
||||||
|
|
||||||
|
while ((1 == 1))
|
||||||
|
do
|
||||||
|
if [ "$1" -gt 0 ] 2>/dev/null;then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
exit 102
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -e /proc/$1 ];then
|
||||||
|
echo "Pid not exist"
|
||||||
|
exit 103
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -e /proc/$1/exe ];then
|
||||||
|
echo "Process exe not exist"
|
||||||
|
exit 105
|
||||||
|
fi
|
||||||
|
|
||||||
|
LIBPTHREAD_PATH=`ldd /proc/$1/exe | grep pthread | awk '{print $3}'`
|
||||||
|
if [ -z "${LIBPTHREAD_PATH}" ];then
|
||||||
|
echo "No pthread"
|
||||||
|
exit 104
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "/proc/$1/root${LIBPTHREAD_PATH}|$1"
|
Binary file not shown.
Binary file not shown.
|
@ -27,6 +27,14 @@
|
||||||
{
|
{
|
||||||
"command": "deadlock-detect.open",
|
"command": "deadlock-detect.open",
|
||||||
"title": "C/C++程序死锁检测"
|
"title": "C/C++程序死锁检测"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "deadlock-detect.analysepid",
|
||||||
|
"title": "C/C++程序进程锁分析"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "deadlock-detect.analyseremotepid",
|
||||||
|
"title": "C/C++程序远程进程锁分析"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"taskDefinitions": [
|
"taskDefinitions": [
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import * as child from 'child_process';
|
||||||
|
import {execDetect, testPwd, prase_yaml2html} from './utils';
|
||||||
|
import { dirname, join } from 'path';
|
||||||
|
import { kill } from 'process';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
const checkTool: string = join(dirname(__dirname), "detect-tools/pidcheck.sh");
|
||||||
|
var intervalObj: NodeJS.Timer;
|
||||||
|
|
||||||
|
function execCheckTool(pwd: string, checkedPid: number, cb: (code: number, da:string)=> void): child.ChildProcess {
|
||||||
|
return child.exec(`echo ${pwd} | sudo -S ${checkTool} ${checkedPid}`, (err, out, e)=>{
|
||||||
|
child.exec(`sudo -k`);
|
||||||
|
if(err?.code){
|
||||||
|
cb(err.code, "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(out.length){
|
||||||
|
cb(0, out);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTerm(checkedPid:number, task: child.ChildProcess): vscode.Pseudoterminal {
|
||||||
|
const writeEmitter = new vscode.EventEmitter<string>();
|
||||||
|
const closeEmitter = new vscode.EventEmitter<number>();
|
||||||
|
var intervalObj: NodeJS.Timer;
|
||||||
|
const pty: vscode.Pseudoterminal = {
|
||||||
|
onDidWrite: writeEmitter.event,
|
||||||
|
onDidClose: closeEmitter.event,
|
||||||
|
open: () => {
|
||||||
|
writeEmitter.fire(`正在分析进程${checkedPid}锁信息,关闭终端或输入q后停止...\r\n`);
|
||||||
|
function intervalFunc(we: vscode.EventEmitter<string>) {
|
||||||
|
we.fire('...');
|
||||||
|
}
|
||||||
|
intervalObj = setInterval(intervalFunc, 1500, writeEmitter);
|
||||||
|
},
|
||||||
|
close: () => {
|
||||||
|
task.kill(9);
|
||||||
|
closeEmitter.fire(0);
|
||||||
|
},
|
||||||
|
handleInput: data => {
|
||||||
|
if (data === 'q') {
|
||||||
|
writeEmitter.fire(`\r\n停止进程${checkedPid}锁分析\r\n`);
|
||||||
|
clearInterval(intervalObj);
|
||||||
|
task.kill(9);
|
||||||
|
// closeEmitter.fire(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return pty;
|
||||||
|
}
|
||||||
|
|
||||||
|
function localPidAnalyse(pid: number, passwd:string, context: vscode.ExtensionContext) {
|
||||||
|
// var term = new MyCustomBuildTaskTerminal(pid);
|
||||||
|
// term.open(undefined);
|
||||||
|
var binPath = fs.readlinkSync(`/proc/${pid}/exe`, {encoding:'utf-8'});
|
||||||
|
let task = execCheckTool(passwd, pid, (code, out)=>{
|
||||||
|
if(out.length){
|
||||||
|
if(out.match(/fatal/)?.length){
|
||||||
|
vscode.window.showWarningMessage("被检测程序存在严重问题!");
|
||||||
|
}else if(out.match(/deadlock/)?.length){
|
||||||
|
vscode.window.showWarningMessage("被检测程序存在死锁!");
|
||||||
|
}
|
||||||
|
if(out.match(/normal|fatal|deadlock/)?.length){
|
||||||
|
const webPanel = vscode.window.createWebviewPanel(
|
||||||
|
'detectResultWebview',
|
||||||
|
"检测结果",
|
||||||
|
vscode.ViewColumn.One,
|
||||||
|
{
|
||||||
|
enableScripts: true,
|
||||||
|
retainContextWhenHidden: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
webPanel.webview.html = prase_yaml2html(binPath, context.extensionPath, webPanel.webview, out);
|
||||||
|
}else{
|
||||||
|
vscode.window.showInformationMessage("未检测到相关锁信息");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (code) {
|
||||||
|
case 100:
|
||||||
|
vscode.window.showInformationMessage("当前Kernel不支持");
|
||||||
|
break;
|
||||||
|
case 101:
|
||||||
|
vscode.window.showInformationMessage("未检测到相关锁信息");
|
||||||
|
break;
|
||||||
|
case 102:
|
||||||
|
vscode.window.showInformationMessage("未检测到相关锁信息");
|
||||||
|
break;
|
||||||
|
case 103:
|
||||||
|
vscode.window.showInformationMessage("未检测到相关锁信息");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
vscode.window.showInformationMessage("未检测到相关锁信息");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var pty = createTerm(pid, task);
|
||||||
|
vscode.window.createTerminal({name:`检测进程${pid}`, pty}).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
function remotePidAnalyse(pid: number, userAndhost: string, passwd: string) {
|
||||||
|
var cmd: child.ChildProcessWithoutNullStreams;
|
||||||
|
cmd = child.spawn(checkTool, [pid.toString()]);
|
||||||
|
cmd.on("error", (err)=>{
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
cmd.stderr.on("data", (data)=>{
|
||||||
|
|
||||||
|
});
|
||||||
|
cmd.stdout.on("data", (data)=>{
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 本地进程锁分析
|
||||||
|
export function DoLocalPidLockAnalyse(context: vscode.ExtensionContext) {
|
||||||
|
vscode.window.showInputBox({
|
||||||
|
ignoreFocusOut:true, // 默认false,设置为true时鼠标点击别的地方输入框不会消失
|
||||||
|
placeHolder:'请输入本地进程PID', // 在输入框内的提示信息
|
||||||
|
prompt:'请输入本地进程PID',
|
||||||
|
validateInput: function (text) {
|
||||||
|
if(!isNaN(Number(text))){
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}).then((data)=>{
|
||||||
|
if(data === undefined || data?.length === 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let pid = Number(data);
|
||||||
|
fs.access(`/proc/${pid}`, fs.constants.F_OK, (err)=>{
|
||||||
|
if(err){
|
||||||
|
vscode.window.showErrorMessage(`进程${pid}不存在`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vscode.window.showInputBox({
|
||||||
|
password: true,
|
||||||
|
ignoreFocusOut:true, // 默认false,设置为true时鼠标点击别的地方输入框不会消失
|
||||||
|
placeHolder:'请输入密码', // 在输入框内的提示信息
|
||||||
|
prompt:'请输入当前用户密码'
|
||||||
|
}).then((data)=>{
|
||||||
|
if(data === undefined || data.length === 0){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
testPwd(data, (ok)=>{
|
||||||
|
if(!ok){
|
||||||
|
vscode.window.showErrorMessage("当前用户密码错误!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
localPidAnalyse(pid, data, context);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 远程进程锁分析
|
||||||
|
export function DoRemotePidLockAnalyse(context: vscode.ExtensionContext) {
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import {DetectTaskProvider} from './detectTaskProvider';
|
||||||
import { homedir } from 'os';
|
import { homedir } from 'os';
|
||||||
import {exec} from 'child_process';
|
import {exec} from 'child_process';
|
||||||
import {testPwd} from './utils';
|
import {testPwd} from './utils';
|
||||||
|
import {DoLocalPidLockAnalyse, DoRemotePidLockAnalyse} from './analysePid';
|
||||||
// linux命令操作模块
|
// linux命令操作模块
|
||||||
var child = require('child_process');
|
var child = require('child_process');
|
||||||
const { pid } = require('process');
|
const { pid } = require('process');
|
||||||
|
@ -141,6 +142,14 @@ export function activate(context: vscode.ExtensionContext) {
|
||||||
});
|
});
|
||||||
panel.webview.html = getWebViewContent(context, 'dist/index.html');
|
panel.webview.html = getWebViewContent(context, 'dist/index.html');
|
||||||
});
|
});
|
||||||
|
// 进程锁分析
|
||||||
|
let disposable0 = vscode.commands.registerCommand('deadlock-detect.analysepid',(context)=>{
|
||||||
|
DoLocalPidLockAnalyse(context);
|
||||||
|
});
|
||||||
|
// 远程进程锁分析
|
||||||
|
let disposable1 = vscode.commands.registerCommand('deadlock-detect.analyseremotepid',(context)=>{
|
||||||
|
DoRemotePidLockAnalyse(context);
|
||||||
|
});
|
||||||
exec(`which sshpass`, (e, o, err)=>{
|
exec(`which sshpass`, (e, o, err)=>{
|
||||||
if(e){
|
if(e){
|
||||||
vscode.window.showWarningMessage('当前环境缺失sshpass工具,C/C++程序远程死锁检测功能受限,请执行 sudo apt install sshpass 安装.');
|
vscode.window.showWarningMessage('当前环境缺失sshpass工具,C/C++程序远程死锁检测功能受限,请执行 sudo apt install sshpass 安装.');
|
||||||
|
@ -161,7 +170,7 @@ export function activate(context: vscode.ExtensionContext) {
|
||||||
detectTaskProvider = vscode.tasks.registerTaskProvider(DetectTaskProvider.customBuildScriptType, new DetectTaskProvider(workspaceRoot, context));
|
detectTaskProvider = vscode.tasks.registerTaskProvider(DetectTaskProvider.customBuildScriptType, new DetectTaskProvider(workspaceRoot, context));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
context.subscriptions.push(disposable);
|
context.subscriptions.push(...[disposable,disposable0,disposable1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this method is called when your extension is deactivated
|
// this method is called when your extension is deactivated
|
||||||
|
|
Loading…
Reference in New Issue