pykd, как расширении к WinDbg, дает не только возможность использования мощного и гибкого языка Python, но и уже готовых сторонних проектов. Далее пойдет речь о PySide - библиотеке интеграции инструментария Qt в Python. Возьмем простой пример: нужно просмотреть статистику о процессах системы, в частноти размер виртуального адресного пространства и счетчики операций ввода/вывода. Не буду рассказывать об установке PySide, так как на официальной странице загрузок для Windows можно скачать инсталлятор. Набросаем небольшой скрипт, который средствами pykd получает и анализирует список процессов, а затем использует PySide для визуализации собранных данных в виде таблицы в GUI-окне:
import sysТеперь исполним его в WinDbg. После того, как скрипт построит список процессов, мы увидим окно результатов. Оно не является модальным по отношению к основному окну WinDbg, но отладчик терпеливо ждет завершения работы скрипта (в нашем случае - закрытия окна):
from pykd import *
from PySide import QtCore, QtGui
COL_PID = 0
COL_PRC_NAME = 1
COL_VSIZE = 2
COL_READ = 3
COL_WRITE = 4
COL_OTHER = 5
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
nt = loadModule( "nt" )
lstProcesses = typedVarList(nt.PsActiveProcessHead, "nt", "_EPROCESS", "ActiveProcessLinks")
countOfProcesses = len(lstProcesses)
if (countOfProcesses == 0):
print "Build process list failed"
sys.exit()
model = QtGui.QStandardItemModel(countOfProcesses, COL_OTHER+1)
model.setHeaderData(COL_PID, QtCore.Qt.Horizontal, "PID")
model.setHeaderData(COL_PRC_NAME, QtCore.Qt.Horizontal, "Image")
model.setHeaderData(COL_VSIZE, QtCore.Qt.Horizontal, "VirtualSize")
model.setHeaderData(COL_READ, QtCore.Qt.Horizontal, "Read")
model.setHeaderData(COL_WRITE, QtCore.Qt.Horizontal, "Write")
model.setHeaderData(COL_OTHER, QtCore.Qt.Horizontal, "Other")
tableView = QtGui.QTableView()
tableView.setModel(model)
for row in range(countOfProcesses):
process = lstProcesses[row]
index_ = model.index(row, COL_PID, QtCore.QModelIndex())
model.setData(index_, process.UniqueProcessId)
index_ = model.index(row, COL_PRC_NAME, QtCore.QModelIndex())
model.setData(index_, "".join([chr(i) for i in process.ImageFileName.values()]))
index_ = model.index(row, COL_VSIZE, QtCore.QModelIndex())
model.setData(index_, process.VirtualSize)
index_ = model.index(row, COL_READ, QtCore.QModelIndex())
model.setData(index_, process.ReadOperationCount.QuadPart)
index_ = model.index(row, COL_WRITE, QtCore.QModelIndex())
model.setData(index_, process.WriteOperationCount.QuadPart)
index_ = model.index(row, COL_OTHER, QtCore.QModelIndex())
model.setData(index_, process.OtherOperationCount.QuadPart)
tableView.resizeColumnsToContents()
widthWidget = 0
for col in range(COL_OTHER+1): widthWidget += tableView.columnWidth(col)
widthWidget += 50
tableView.setSortingEnabled(True)
tableView.setWindowTitle("Processes table:")
tableView.resize(widthWidget, 500)
tableView.show()
app.exec_()
Конечно, можно было бы выдать эту информацию в текстовой форме. Но GUI таблица, например, позволяет одним кликом поменять колонку сортировки и можно наблюдать какой процесс активно более активно читает, а какой пишет.
Еще один приятный момент использования PySide - лицензия LGPL, позволяющая использовать и распространять библиотеку в любых проектах, включая коммерческие.
Еще один приятный момент использования PySide - лицензия LGPL, позволяющая использовать и распространять библиотеку в любых проектах, включая коммерческие.
Спасибо за идею и за удачный пример!
ОтветитьУдалить> airmax комментирует...
ОтветитьУдалить> Спасибо за идею и за удачный пример!
Всегда пожалуйста :)
Если появляется ошибка "A QApplication instance already exists", см сюда:
ОтветитьУдалитьhttp://pykd.blogspot.com/2011/06/qt-qapplication-instance-already-exists.html