Skip to content

Commit

Permalink
Valgrind plugin:
Browse files Browse the repository at this point in the history
    Toolbar in MemCheck's output pane is horizontal now (in accordance to the latest CL's design rules).
    Terminal emulator is used for running of checked application so users can better interact with it.
Fixed: eranif#906
    missing data in Locals/Watches windows
  • Loading branch information
eranif committed Oct 2, 2015
1 parent 8445a8d commit a681f6e
Show file tree
Hide file tree
Showing 7 changed files with 1,331 additions and 1,314 deletions.
57 changes: 35 additions & 22 deletions Debugger/debuggergdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,18 +169,32 @@ void DbgGdb::RegisterHandler(const wxString& id, DbgCmdHandler* cmd) { m_handler

DbgCmdHandler* DbgGdb::PopHandler(const wxString& id)
{
HandlersMap::iterator it = m_handlers.find(id);
// Check if we got some gaps in the protocol
// long nId;
// id.ToCLong(&nId);
// --nId;
// wxString oldId = wxString::Format(wxT("%08d"), (int)nId);

HandlersMap_t::iterator it = m_handlers.find(id);
if(it == m_handlers.end()) {
return NULL;
}

DbgCmdHandler* cmd = it->second;
m_handlers.erase(it);
// if(it != m_handlers.begin()) {
// --it;
// if(it->first != oldId) {
// CL_WARNING("Request to process handler %s while handler %s is still in the queue!!", id, it->first);
// }
// ++it;
// }
m_handlers.erase(id);
return cmd;
}

void DbgGdb::EmptyQueue()
{
HandlersMap::iterator iter = m_handlers.begin();
HandlersMap_t::iterator iter = m_handlers.begin();
while(iter != m_handlers.end()) {
delete iter->second;
iter++;
Expand Down Expand Up @@ -260,6 +274,7 @@ bool DbgGdb::WriteCommand(const wxString& command, DbgCmdHandler* handler)
cmd << id << command;

if(!ExecuteCmd(cmd)) {
CL_WARNING("Failed to send command: %s", cmd);
return false;
}
RegisterHandler(id, handler);
Expand Down Expand Up @@ -562,17 +577,20 @@ bool DbgGdb::QueryLocals() { return WriteCommand(wxT("-stack-list-variables 2"),

bool DbgGdb::ExecuteCmd(const wxString& cmd)
{
static wxLongLong commandsCounter = 0;
if(m_gdbProcess) {
if(m_info.enableDebugLog) {
#if DBG_LOG
if(gfp.IsOpened()) {
gfp.Write(wxString::Format(wxT("DEBUG>>%s\n"), cmd.c_str()));
gfp.Flush();
}
#else
m_observer->UpdateAddLine(wxString::Format(wxT("DEBUG>>%s"), cmd.c_str()));
#endif
CL_DEBUG("DEBUG>>%s", cmd);
m_observer->UpdateAddLine(wxString::Format(wxT("DEBUG>>%s"), cmd));
}
#ifdef __WXMSW__
// Ugly hack to fix bug https://github.com/eranif/codelite/issues/906
if(commandsCounter >= 50) {
::wxMilliSleep(1);
commandsCounter = 0;
}
#endif
++commandsCounter;
return m_gdbProcess->Write(cmd);
}
return false;
Expand Down Expand Up @@ -646,14 +664,8 @@ void DbgGdb::Poke()
if(curline.IsEmpty() == false && !tmpline.StartsWith(wxT(">"))) {
wxString strdebug(wxT("DEBUG>>"));
strdebug << curline;
#if DBG_LOG
if(gfp.IsOpened()) {
gfp.Write(strdebug);
gfp.Flush();
}
#else
CL_DEBUG(strdebug);
m_observer->UpdateAddLine(strdebug);
#endif
}
}

Expand Down Expand Up @@ -1144,6 +1156,7 @@ bool DbgGdb::EvaluateVariableObject(const wxString& name, int userReason)
{
wxString cmd;
cmd << wxT("-var-evaluate-expression \"") << name << wxT("\"");
// CL_DEBUG("GDB>> %s", cmd);
return WriteCommand(cmd, new DbgCmdEvalVarObj(m_observer, name, userReason));
}

Expand Down Expand Up @@ -1235,10 +1248,10 @@ bool DbgGdb::SetVariableObbjectDisplayFormat(const wxString& name, DisplayFormat
bool DbgGdb::UpdateVariableObject(const wxString& name, int userReason)
{
// FIXME: this seems to cause a mess in gdb output, disable it for now
//wxString cmd;
//cmd << wxT("-var-update \"") << name << wxT("\" ");
//return WriteCommand(cmd, new DbgVarObjUpdate(m_observer, this, name, userReason));

// wxString cmd;
// cmd << wxT("-var-update \"") << name << wxT("\" ");
// return WriteCommand(cmd, new DbgVarObjUpdate(m_observer, this, name, userReason));
return true;
}

Expand Down
5 changes: 3 additions & 2 deletions Debugger/debuggergdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,14 @@ class DbgCmdHandler;
class DbgCmdCLIHandler;
class IProcess;

WX_DECLARE_STRING_HASH_MAP(DbgCmdHandler*, HandlersMap);

typedef std::map<wxString, DbgCmdHandler*> HandlersMap_t;

extern const wxEventType wxEVT_GDB_STOP_DEBUGGER;

class DbgGdb : public wxEvtHandler, public IDebugger
{
HandlersMap m_handlers;
HandlersMap_t m_handlers;
long m_debuggeePid;
ConsoleFinder m_consoleFinder;
std::vector<BreakpointInfo> m_bpList;
Expand Down
46 changes: 24 additions & 22 deletions MemCheck/memcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ extern "C" EXPORT PluginInfo GetPluginInfo()
info.SetAuthor(wxT("pavel.iqx"));
info.SetName(wxT("MemCheck"));
info.SetDescription(_("MemCheck plugin detects memory leaks. Uses Valgrind (memcheck tool) as backend."));
info.SetVersion(wxT("0.4"));
info.SetVersion(wxT("0.5"));
return info;
}

Expand All @@ -51,10 +51,9 @@ extern "C" EXPORT int GetPluginInterfaceVersion() { return PLUGIN_INTERFACE_VERS
MemCheckPlugin::MemCheckPlugin(IManager* manager)
: IPlugin(manager)
, m_memcheckProcessor(NULL)
, m_process(NULL)
{
Bind(wxEVT_ASYNC_PROCESS_OUTPUT, &MemCheckPlugin::OnProcessOutput, this);
Bind(wxEVT_ASYNC_PROCESS_TERMINATED, &MemCheckPlugin::OnProcessTerminated, this);
m_terminal.Bind(wxEVT_TERMINAL_COMMAND_EXIT, &MemCheckPlugin::OnProcessTerminated, this);
m_terminal.Bind(wxEVT_TERMINAL_COMMAND_OUTPUT, &MemCheckPlugin::OnProcessOutput, this);

// CL_DEBUG1(PLUGIN_PREFIX("MemCheckPlugin constructor"));
m_longName = _("Detects memory management problems. Uses Valgrind - memcheck skin.");
Expand Down Expand Up @@ -152,7 +151,6 @@ MemCheckPlugin::~MemCheckPlugin()
// CL_DEBUG1(PLUGIN_PREFIX("MemCheckPlugin destroyed"));
wxDELETE(m_memcheckProcessor);
wxDELETE(m_settings);
wxDELETE(m_process);
}

clToolBar* MemCheckPlugin::CreateToolBar(wxWindow* parent)
Expand Down Expand Up @@ -332,9 +330,9 @@ void MemCheckPlugin::UnHookPopupMenu(wxMenu* menu, MenuType type)

void MemCheckPlugin::UnPlug()
{
Unbind(wxEVT_ASYNC_PROCESS_OUTPUT, &MemCheckPlugin::OnProcessOutput, this);
Unbind(wxEVT_ASYNC_PROCESS_TERMINATED, &MemCheckPlugin::OnProcessTerminated, this);

m_terminal.Unbind(wxEVT_TERMINAL_COMMAND_EXIT, &MemCheckPlugin::OnProcessTerminated, this);
m_terminal.Unbind(wxEVT_TERMINAL_COMMAND_OUTPUT, &MemCheckPlugin::OnProcessOutput, this);
m_mgr->GetTheApp()->Disconnect(XRCID("memcheck_check_active_project"),
wxEVT_COMMAND_MENU_SELECTED,
wxCommandEventHandler(MemCheckPlugin::OnCheckAtiveProject),
Expand Down Expand Up @@ -423,7 +421,7 @@ void MemCheckPlugin::OnWorkspaceClosed(wxCommandEvent& event)

bool MemCheckPlugin::IsReady(wxUpdateUIEvent& event)
{
bool ready = !m_mgr->IsBuildInProgress() && m_process == NULL;
bool ready = !m_mgr->IsBuildInProgress() && !m_terminal.IsRunning();
int id = event.GetId();
if(id == XRCID("memcheck_check_active_project")) {
ready &= !m_mgr->GetWorkspace()->GetActiveProjectName().IsEmpty();
Expand Down Expand Up @@ -482,8 +480,12 @@ void MemCheckPlugin::OnCheckPopupEditor(wxCommandEvent& event)

void MemCheckPlugin::CheckProject(const wxString& projectName)
{
if(m_process)
return; // a process is already running
if( m_terminal.IsRunning() ) {
::wxMessageBox(_("Another instance is already running. Please stop it before executing another one"),
"CodeLite",
wxICON_WARNING | wxCENTER | wxOK);
return;
}

wxString errMsg;
ProjectPtr project = m_mgr->GetWorkspace()->FindProjectByName(projectName, errMsg);
Expand All @@ -502,7 +504,9 @@ void MemCheckPlugin::CheckProject(const wxString& projectName)
m_mgr->AppendOutputTabText(kOutputTab_Output,
wxString() << "MemCheck command: " << m_memcheckProcessor->GetExecutionCommand(command)
<< "\n");
m_process = ::CreateAsyncProcess(this, m_memcheckProcessor->GetExecutionCommand(command));

wxString cmd = m_memcheckProcessor->GetExecutionCommand(command);
m_terminal.ExecuteConsole(cmd, "", true, wxString::Format("MemCheck: %s", projectName));
}

void MemCheckPlugin::OnImportLog(wxCommandEvent& event)
Expand Down Expand Up @@ -545,21 +549,16 @@ void MemCheckPlugin::OnMemCheckUI(wxUpdateUIEvent& event)

void MemCheckPlugin::StopProcess()
{
if(m_process) {
wxKill(m_process->GetPid(), wxSIGINT);
// m_process->Terminate();
}
if( m_terminal.IsRunning() ) m_terminal.Terminate();
}

void MemCheckPlugin::OnProcessOutput(clProcessEvent& event)
void MemCheckPlugin::OnProcessOutput(clCommandEvent& event)
{
m_mgr->AppendOutputTabText(kOutputTab_Output, event.GetOutput());
m_mgr->AppendOutputTabText(kOutputTab_Output, event.GetString());
}

void MemCheckPlugin::OnProcessTerminated(clProcessEvent& event)
void MemCheckPlugin::OnProcessTerminated(clCommandEvent& event)
{
wxDELETE(m_process);

m_mgr->AppendOutputTabText(kOutputTab_Output, _("\n-- MemCheck process completed\n"));
wxWindowDisabler disableAll;
wxBusyInfo wait(wxT(BUSY_MESSAGE));
Expand All @@ -576,4 +575,7 @@ void MemCheckPlugin::OnStopProcess(wxCommandEvent& event)
StopProcess();
}

void MemCheckPlugin::OnStopProcessUI(wxUpdateUIEvent& event) { event.Enable(IsRunning()); }
void MemCheckPlugin::OnStopProcessUI(wxUpdateUIEvent& event)
{
event.Enable(IsRunning());
}
11 changes: 6 additions & 5 deletions MemCheck/memcheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

#include "memcheckui.h"
#include "imemcheckprocessor.h"
#include "TerminalEmulator.h"

class IProcess;
class AsyncExeCmd;
class MemCheckOutputView;

Expand Down Expand Up @@ -55,15 +55,16 @@ class MemCheckPlugin : public IPlugin
* @brief return true if a test is currently running
* @return
*/
bool IsRunning() const { return m_process != NULL; }
// bool IsRunning() const { return m_process != NULL; }
bool IsRunning() const { return m_terminal.IsRunning(); }

protected:
MemCheckIcons16 m_icons16;
MemCheckIcons24 m_icons24;

IMemCheckProcessor* m_memcheckProcessor;
MemCheckSettings* m_settings;
IProcess* m_process; ///< Test is run as external tool.
TerminalEmulator m_terminal;
MemCheckOutputView* m_outputView; ///< Main plugin UI pane.

void OnWorkspaceLoaded(wxCommandEvent& event);
Expand Down Expand Up @@ -110,8 +111,8 @@ class MemCheckPlugin : public IPlugin
*/
void CheckProject(const wxString& projectName);

void OnProcessOutput(clProcessEvent& event);
void OnProcessTerminated(clProcessEvent& event);
void OnProcessOutput(clCommandEvent& event);
void OnProcessTerminated(clCommandEvent& event);

/**
* @brief Analyse can be made independent of CodeLite and log can be load from file.
Expand Down
4 changes: 2 additions & 2 deletions MemCheck/memcheckui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,10 @@ MemCheckOutputViewBase::MemCheckOutputViewBase(wxWindow* parent, wxWindowID id,
bBitmapLoaded = true;
}

wxBoxSizer* boxSizer221 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* boxSizer221 = new wxBoxSizer(wxVERTICAL);
this->SetSizer(boxSizer221);

m_auibar223 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxSize(-1,-1), wxAUI_TB_PLAIN_BACKGROUND|wxAUI_TB_DEFAULT_STYLE|wxAUI_TB_VERTICAL);
m_auibar223 = new wxAuiToolBar(this, wxID_ANY, wxDefaultPosition, wxSize(-1,-1), wxAUI_TB_PLAIN_BACKGROUND|wxAUI_TB_DEFAULT_STYLE);
m_auibar223->SetToolBitmapSize(wxSize(16,16));

boxSizer221->Add(m_auibar223, 0, wxALL|wxEXPAND, 0);
Expand Down
4 changes: 2 additions & 2 deletions MemCheck/memcheckui.wxcp
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@
}, {
"type": "choice",
"m_label": "Orientation:",
"m_selection": 1,
"m_selection": 0,
"m_options": ["wxVERTICAL", "wxHORIZONTAL"]
}],
"m_events": [],
Expand All @@ -429,7 +429,7 @@
"border": 0,
"gbSpan": "1,1",
"gbPosition": "0,0",
"m_styles": ["wxAUI_TB_PLAIN_BACKGROUND", "wxAUI_TB_DEFAULT_STYLE", "wxAUI_TB_VERTICAL"],
"m_styles": ["wxAUI_TB_PLAIN_BACKGROUND", "wxAUI_TB_DEFAULT_STYLE"],
"m_sizerFlags": ["wxALL", "wxLEFT", "wxRIGHT", "wxTOP", "wxBOTTOM", "wxEXPAND"],
"m_properties": [{
"type": "winid",
Expand Down
Loading

0 comments on commit a681f6e

Please sign in to comment.