Page 1 of 1

wxExecute fails inside CL plugin

Posted: Sun Apr 07, 2013 1:53 am
by petah
Hi Eran,

calling wxExecute() from a CL plugin returns -1 ("failed to execute") instead of 0, with wx logging "Debug: In file ../src/unix/utilsunx.cpp at line 1502: waitpid(16177)' failed with error 0x0000000a (No child processes)."

Ignoring the return code and accessing wxProcess::GetInputStream() does work so it seems it's just a bad error code. Variants like wxExecute(cmd, wxArrayString &output) don't work because wxDoExecuteWithCapture() (in wx/src/common/utilscmn.cpp) doesn't write to output if rc == -1.

I logged a few CL functions (see below) and ChildTerminatedSingalHandler() is called on all processes, even those not created by IProcess. The test code that produced the logs is attached.

I couldn't figure out a fix, assuming this actually is a bug. Maybe you can determine if a pid belongs to an IProcess (with a hashset or else) and if not let it pass through your signal handler or add a wrapper around IPlugin functions to shield processes it spawns... or something simpler.

thx & cheers,

-- p

platform: CL trunk, Debian/Gtk Wheezy x64, tested with wx294 & wx Trunk

Log when called from a CL plugin:

Code: Select all

UnixProcessImpl::Terminate(pid 5246)
IProcess::SetProcessExitCode(pid 5246, exitcode 0)
ChildTerminatedSingalHandler signo(17), pid(5246), status(15)
IProcess::SetProcessExitCode(pid 5249, exitcode 0)
ChildTerminatedSingalHandler signo(17), pid(5249), status(0)
IProcess::SetProcessExitCode(pid 5251, exitcode 0)
ChildTerminatedSingalHandler signo(17), pid(5251), status(0)
LocateApp("gprof")
IProcess::SetProcessExitCode(pid 5261, exitcode 0)
ChildTerminatedSingalHandler signo(17), pid(5261), status(0)
22:41:57: Debug: In file ../src/unix/utilsunx.cpp at line 1502: 'waitpid(5261)' failed with error 0x0000000a (No child processes).
  wxExecute("which gprof") returned err -1, got 0 lines
LocateApp() returned "<ERROR>"
TestProcess("gprof")
IProcess::SetProcessExitCode(pid 5264, exitcode 0)
ChildTerminatedSingalHandler signo(17), pid(5264), status(0)
22:41:57: Debug: In file ../src/unix/utilsunx.cpp at line 1502: 'waitpid(5264)' failed with error 0x0000000a (No child processes).
  wxExecute("which gprof") returned err -1, had pid 5264
  returned "/usr/bin/gprof"
TestProcess() returned "/usr/bin/gprof"
CallGraph::GetGprofPath() : "/usr/bin/gprof"
CallGraph::CallGraph() initialized
Log when called from outside CL:

Code: Select all

2013-04-06 23:07:28 : TestProcess("gprof")
2013-04-06 23:07:28 :   wxExecute("which gprof") returned err 0, had pid 7169
2013-04-06 23:07:28 :   returned "/usr/bin/gprof"
2013-04-06 23:07:28 :   TestProcess() returned "/usr/bin/gprof"
2013-04-06 23:07:28 : LocateApp("gprof")
2013-04-06 23:07:28 :   wxExecute("which gprof") returned err 0, got 1 lines
2013-04-06 23:07:28 :   returned "/usr/bin/gprof"
2013-04-06 23:07:28 :   LocateApp() returned "/usr/bin/gprof"

Re: wxExecute fails inside CL plugin

Posted: Sun Apr 07, 2013 7:49 am
by eranif
This is strange as I am rarely if any is using wxExecute(...)
Instead codelite has its own ::CreateAsyncProcess(..) API which is much more convinient and reliable

Can you replace the wxExecute call with CreateAsyncProcess?

Eran

Re: wxExecute fails inside CL plugin

Posted: Sun Apr 07, 2013 8:55 am
by petah
Not sure, I'm patching the CallGraph plugin which in one place connects the wxProcess inputStream directly into its custom gprof parser. Other occurances use sync processes, it'd take some more work to make everything async.

thx,

-- p

Re: wxExecute fails inside CL plugin

Posted: Sun Apr 07, 2013 9:06 am
by eranif
petah wrote:Not sure, I'm patching the CallGraph plugin which in one place connects the wxProcess inputStream directly into its custom gprof parser. Other occurances use sync processes, it'd take some more work to make everything async.

thx,

-- p
The problem with this plugin is that I never used it ;)
( I simply applied it to trunk )
But as a rule of thumb, all process should be created with codeite's ::CreateAsyncProcess API
If you can fix this it will be great

Eran

Re: wxExecute fails inside CL plugin

Posted: Sun Apr 07, 2013 10:02 am
by petah
I'm not surprised, it's a real spaghetti bowl. I had it working an hour or so ago, then broke it again somehow.

I can probably fix it but I'm not very confident in the code; I already replaced all the manual path building that had hardcoded / and \ with wxFileName::AppendDir() and such but the parser still has explosive-looking 'new char []' stuff all over the place.

Also because it's based on gprof it's not a real call graph; you need to set the thresholds really low to see anything on an event-based app where the CPU is idle most of the time. Had I known that earlier I probably would have looked for some other graph generator but now that I invested the time...

Btw I'd be really useful to have a cmd-line arg like --volatile-config $temp_path to copy CL's prefs to a temp dir so spawned CL instances don't fight over the debug log and other prefs.

-- p

Re: wxExecute fails inside CL plugin

Posted: Sun Apr 07, 2013 5:00 pm
by petah
here's a somewhat less crufty version, IMO it's not worth pursuing.

The node threshold equates a function's total CPU % so it typically needs to be set under 5% to display anything and what trickles through is irrelevant:
CallGraph.png
I can't think of a project that would benefit from it nowadays; if someone does please chime in. The source code is no walk in the park either, it looks like an automatic translation from another language because there are so many repetitions.

I'm looking for interactive visualization of large C++ projects to understand architecture and help refactoring which this plugin can never achieve because it's gprof-based. It'd probably make more sense to extract information directly from the ctags database to generate a .dot file manually and call graphviz only for layout/rendering.

If someone has pointers to existing libs that could be wrapped into a CL plugin let me know...

cheers,

-- p

Re: wxExecute fails inside CL plugin

Posted: Mon Apr 08, 2013 9:26 pm
by petah
Hey,

here's a patch for CL trunk; it runs on Linux and should on Windows too.

It's not async but ignoring the wxExecute() return code works; it checks the input stream before using it. Windows shouldn't be affected since your signal handler isn't installed on it.

When the threshold settings are too low to produce a graph, it'll now say what the ceiling is so users know what to adjust them too.

cheers,

-- p

Re: wxExecute fails inside CL plugin

Posted: Wed Apr 10, 2013 12:36 pm
by petah
caveat for Windows compat:

the Linux version assumes there are no spaces in the full paths to commands (gprof, dot) and data files (gmon.out, <project_dir>, dot.txt, dot.png). On Windows those have to be enquoted/escaped, esp. since utils are probably inside "C:\Program Files\".

There's only a handful of occurances you'll find before wxExecute() calls. Command-lines passed to it always have the form:

Code: Select all

cmd file1 file2
those 3 strings should each be enquoted.

cheers,

-- p

Re: wxExecute fails inside CL plugin

Posted: Thu Apr 11, 2013 10:33 am
by eranif
Patch applied to git head.

Eran

Re: wxExecute fails inside CL plugin

Posted: Thu Apr 11, 2013 3:39 pm
by petah
I might have been wrong about CallGraph being unsuitable; I just tried another callgraph generator and its GraphViz output is also overwhelmed by wx symbols, drowning out the client app functions. I'll try to filter those out when I get the chance.

Do you want to create a new CallGraph section in the plugins board?

thx & cheers,

-- p