⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gexmap.cpp

📁 内存管理工具Exmap。该工具比 ps 或 top 更精确
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * (c) John Berthels 2005 <jjberthels@gmail.com>. See COPYING for license. */#include <gtkmm.h>#include <gtkmm/window.h>#include "Exmap.hpp"#include "jutil.hpp"#include <boost/shared_ptr.hpp>#include <sstream>#include <iostream>#include <list>namespace Gexmap{    typedef boost::shared_ptr<Gtk::Widget> WidgetPtr;        /// Abstract base class for all the list. This will automatically    /// add in the columns needed for 'Sizes' after those added by the    /// subclass, as well as setting up conveniences such as    /// scrollbars, sortable columns etc.    class SizeListView : public Gtk::Frame    {    public:	SizeListView(const std::string &frame_name);	virtual ~SizeListView();	Gtk::TreeView &listwin();	void update_view();    protected:	/// Call this from your ctor, after adding your columns to	/// _coluns.	void init_store_and_view();	/// Call this from your ctor, after appending your columns to	/// the treeview.	void init_columns();	/// When creating a new Row, call this to add in the values	/// for the Sizes.	void add_row_sizes(Gtk::TreeModel::Row &row,			   Exmap::SizesPtr &sizes);	/// Show the list view (hiding the label), and clear the store	void show_list();	/// Show the label, with this text (hiding the list)	void show_label(const std::string &txt);	/// True if we are showing the list, false if the label	bool showing_list;		Glib::RefPtr<Gtk::ListStore> _store;	// We display either the treeview or the errlabel	Gtk::TreeView _treeview;	Gtk::Label _errlabel;		// Hack: reparent the unused child widget to here	Gtk::Frame _hidden;	/// In the derived class, add columns definitions to this	/// record in your ctor.	Gtk::TreeModel::ColumnRecord _columns;    private:	Gtk::TreeModelColumn<float> _size_columns[Exmap::Sizes::NUM_SIZES];	void _make_all_sortable();	static std::string SIZES_PRINTF_FORMAT;	Gtk::ScrolledWindow _scrolled_window;    };    typedef boost::shared_ptr<SizeListView> SizeListViewPtr;    /// Abstract base class for showing processes in a list    class ProcList : public SizeListView    {    public:	ProcList(const std::string &frame_name);	pid_t currently_selected();    protected:	void add_row(pid_t pid,		     const std::string &cmdline,		     Exmap::SizesPtr &sizes);	Gtk::TreeModelColumn<pid_t> _pid;	Gtk::TreeModelColumn<Glib::ustring> _cmdline;    };	    /// Concrete subclass for showing a top-level list of processes    class AllProcList : public ProcList    {    public:	AllProcList();	void set_data(const std::list<Exmap::ProcessPtr> &procs);    private:	Exmap::SizesPtr calc_totals(const std::list<Exmap::ProcessPtr> &procs);    };        /// Concrete subclass for showing the list of process which map a file    class PerFileProcList : public ProcList    {    public:	PerFileProcList();	void set_data(const Exmap::FilePtr &file);    };        class AllFileList : public SizeListView    {    public:	AllFileList();	void set_data(const std::list<Exmap::FilePtr> &files);	std::string currently_selected();    private:	Gtk::TreeModelColumn<Glib::ustring> _filename;	Gtk::TreeModelColumn<int> _nprocs;    };        /// Concrete subclass for showing all files within a process    class PerProcFileList : public SizeListView    {    public:	PerProcFileList();	void set_data(const Exmap::ProcessPtr &proc);	std::string currently_selected();    private:	Gtk::TreeModelColumn<Glib::ustring> _filename;    };        /// Concrete subclass for showing the elf sections for a specific    /// process and file.    class ElfSectionList : public SizeListView    {    public:	ElfSectionList();	Gtk::TreeModelColumn<Glib::ustring> _name;	Gtk::TreeModelColumn<off_t> _file_offset;	void set_data(const Exmap::ProcessPtr &proc,		      const Exmap::FilePtr &file);	std::string currently_selected();    };        /// Concrete subclass for showing the elf symbols for a specific    /// process, file and elf section    class ElfSymbolList : public SizeListView    {    public:	ElfSymbolList();	Gtk::TreeModelColumn<Glib::ustring> _name;	void set_data(const Exmap::ProcessPtr &proc,		      const Exmap::FilePtr &file,		      const Elf::SectionPtr &section);    };    /// Abstract base class for the file and proc tabs    class ExmapTab : public Gtk::VPaned    {    public:	ExmapTab();	virtual void set_data(Exmap::SnapshotPtr &snapshot) = 0;    protected:	Gtk::VPaned _top_half;	Gtk::VPaned _bottom_half;	// Internal data	Exmap::SnapshotPtr _snapshot;	// Widgets	ElfSectionList _sectionlist;	ElfSymbolList _symlist;    };    /// The 'Files' Tab    class FileTab : public ExmapTab    {    public:	FileTab();	void set_data(Exmap::SnapshotPtr &snapshot);    private:	// Callbacks	void filelist_changed_cb();	void proclist_changed_cb();	void sectionlist_changed_cb();		// Widgets	AllFileList _allfilelist;	PerFileProcList _proclist;    };    /// The 'Processes' Tab    class ProcTab : public ExmapTab    {    public:	ProcTab();	void set_data(Exmap::SnapshotPtr &snapshot);    private:	// Callbacks	void proclist_changed_cb();	void filelist_changed_cb();	void sectionlist_changed_cb();		// Widgets	AllProcList _allproclist;	PerProcFileList _filelist;    };    /// Status and button bar    class BottomBar : public Gtk::HBox    {    public:	BottomBar();	void set_status(Exmap::SnapshotPtr &snapshot);    private:	Gtk::Label _plabel;	Gtk::Label _flabel;	Gtk::Button _quit_button;	// Callbacks	void quit_button_clicked_cb();    };        /// The main, toplevel window    class TopWin : public Gtk::Window    {    public:	TopWin(Exmap::SnapshotPtr &snapshot);	static const int WIDTH = 800;	static const int HEIGHT = 600;    private:	// Internal data	Exmap::SnapshotPtr _snapshot;	// Widgets	ProcTab _proctab;	FileTab _filetab;	Gtk::Notebook _notebook;	Gtk::VBox _vbox;	BottomBar _bottom_bar;    };    };using namespace std;using namespace jutil;using namespace Exmap;using namespace Gexmap;// ------------------------------------------------------------TopWin::TopWin(SnapshotPtr &snapshot)    : _snapshot(snapshot){    add(_vbox);    _notebook.append_page(_proctab, "Processes");    _notebook.append_page(_filetab, "Files");    _vbox.add(_notebook);    _vbox.pack_end(_bottom_bar, false, false);    _proctab.set_data(snapshot);    _filetab.set_data(snapshot);        set_default_size(WIDTH, HEIGHT);    _bottom_bar.set_status(_snapshot);    show_all();}// ------------------------------------------------------------BottomBar::BottomBar(){    _quit_button.set_label("Quit");    _quit_button.signal_clicked()	.connect(sigc::mem_fun(*this, &BottomBar::quit_button_clicked_cb));    add(_plabel);    add(_flabel);    pack_end(_quit_button, false, false);}void BottomBar::quit_button_clicked_cb(){    Gtk::Main::quit();}void BottomBar::set_status(SnapshotPtr &snapshot){    stringstream sstr;    sstr << "Number of procs: " << snapshot->procs().size();    _plabel.set_text(sstr.str());    sstr.str("");    sstr << "Number of files: " << snapshot->files().size();    _flabel.set_text(sstr.str());}// ------------------------------------------------------------SizeListView::SizeListView(const std::string &frame_name)    : Gtk::Frame(frame_name),      showing_list(true){    _hidden.add(_errlabel);    _scrolled_window.add(_treeview);    _scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);    add(_scrolled_window);    _errlabel.show();    _scrolled_window.show_all();}Gtk::TreeView &SizeListView::listwin(){    return _treeview;}SizeListView::~SizeListView(){ }void SizeListView::init_columns(){    Glib::RefPtr<Gtk::TreeModel> model = _treeview.get_model();    int sort_colid = -1;    for (int i = 0; i < Exmap::Sizes::NUM_SIZES; ++i) {	int colid = _treeview.append_column_numeric(Exmap::Sizes::size_name(i),						    _size_columns[i],						    SIZES_PRINTF_FORMAT);		// Remember the number of columns first time round the loop	if (sort_colid < 0) {	    sort_colid = colid - 1;	}    }        _make_all_sortable();    _store->set_sort_column_id(sort_colid, Gtk::SORT_DESCENDING);}void SizeListView::_make_all_sortable(){    int ncols = _columns.size();    Gtk::TreeViewColumn *col;        for (int i = 0; i < ncols; ++i) {	col = _treeview.get_column(i);	col->set_sort_column(i);    }    return;}void SizeListView::init_store_and_view(){    for (int i = 0; i < Exmap::Sizes::NUM_SIZES; ++i) {	_columns.add(_size_columns[i]);    }    _store = Gtk::ListStore::create(_columns);    _treeview.set_model(_store);}void SizeListView::add_row_sizes(Gtk::TreeModel::Row &row,				 Exmap::SizesPtr &sizes){    for (int i = 0; i < Exmap::Sizes::NUM_SIZES; ++i) {	row[_size_columns[i]] = sizes->sval(i);    }}// We scale to kbytes, so support 4G => 4000000-ish max => 7 leading// digits, plus 2 digits after decimal pt plus the pt = 10 chars in// total.string SizeListView::SIZES_PRINTF_FORMAT("%.2f");void SizeListView::show_label(const string &txt){    _errlabel.set_text(txt);    if (!showing_list) { return; }    Gtk::Frame tmp;    _errlabel.reparent(tmp);    _scrolled_window.reparent(_hidden);    _errlabel.reparent(*this);    showing_list = false;}void SizeListView::show_list(){    _store->clear();    if (showing_list) { return; }    Gtk::Frame tmp;    _scrolled_window.reparent(tmp);    _errlabel.reparent(_hidden);    _scrolled_window.reparent(*this);    showing_list = true;}// ------------------------------------------------------------ProcList::ProcList(const std::string &frame_name)    : SizeListView(frame_name){    _columns.add(_pid);    _columns.add(_cmdline);    init_store_and_view();    _treeview.append_column("PID", _pid);    _treeview.append_column("Cmdline", _cmdline);    init_columns();}    pid_t ProcList::currently_selected(){    Glib::RefPtr<Gtk::TreeSelection> sel = listwin().get_selection();    Glib::RefPtr<Gtk::TreeModel> model = listwin().get_model();    pid_t pid = 0; // invalid    if (sel->count_selected_rows() == 1) {	Gtk::TreeModel::iterator iter = sel->get_selected(model);	if (iter) {	    Gtk::TreeModel::Row row = *iter;	    pid = row.get_value(_pid);	}    }    return pid;}void ProcList::add_row(pid_t pid, const string &cmdline, SizesPtr &sizes){    Gtk::TreeModel::Row row = *(_store->append());    row[_pid] = pid;    row[_cmdline] = cmdline;    add_row_sizes(row, sizes);}// ------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -