add check process with pid

This commit is contained in:
Your Name 2022-11-06 18:58:22 +08:00
parent 5bc1030004
commit 09c4c89216
7 changed files with 241 additions and 1 deletions

View File

@ -4,6 +4,16 @@ ARCH=`arch`
DIR=`dirname $0`
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
# echo "Error params"
exit 101

View File

@ -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"

View File

@ -27,6 +27,14 @@
{
"command": "deadlock-detect.open",
"title": "C/C++程序死锁检测"
},
{
"command": "deadlock-detect.analysepid",
"title": "C/C++程序进程锁分析"
},
{
"command": "deadlock-detect.analyseremotepid",
"title": "C/C++程序远程进程锁分析"
}
],
"taskDefinitions": [

View File

@ -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) {
}

View File

@ -7,6 +7,7 @@ import {DetectTaskProvider} from './detectTaskProvider';
import { homedir } from 'os';
import {exec} from 'child_process';
import {testPwd} from './utils';
import {DoLocalPidLockAnalyse, DoRemotePidLockAnalyse} from './analysePid';
// linux命令操作模块
var child = require('child_process');
const { pid } = require('process');
@ -141,6 +142,14 @@ export function activate(context: vscode.ExtensionContext) {
});
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)=>{
if(e){
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));
});
});
context.subscriptions.push(disposable);
context.subscriptions.push(...[disposable,disposable0,disposable1]);
}
// this method is called when your extension is deactivated