flightaware / Tcl-bounties

Bounty program for improvements to Tcl and certain Tcl packages
104 stars 8 forks source link

[Q] Tcl Pro debugger #19

Closed sebres closed 7 years ago

sebres commented 7 years ago

Is only "Tcl Pro package" accepted? I'm asking because...

I've own remote tcl-debugger and tcl-profiler library, that can be integrated into several editors (or IDEs). I use it together with SublimeText.... The library (with my sublimetext integration over python binding) enables me to debug, set breakpoints (also conditional), view and watch variables (also more complex types like dicts, lists, etc.), view the scope, traverse over compiled uplevels as well as show the call stack... Can do step into, trace over, run until return, etc.

Or even in code coverage mode it shows the lines not covered in test-cases.

But it is a library, so without integration into IDE resp. Editor it is just a large piece of code only... If desired I can try to integrate it in some open source editor... Or rewrite as GUI (would be more expensive, and I don't know that to write own IDE or editor would be good idea at all)...

About the profiler, example shows better as words:

===========================================================================================================
Run # 0
  tclSE-servlet-runner (zeus2, PID:16FC, TID:1734)
  # 01-12-2016 | 03:18:35 | Servlet: dev/env/exec | Request: /test-http-geturl-data
===========================================================================================================
          NS | Name                   |     C |     T | Tot(s) | TwR(s) | Avg(s) | AwR(s) | Max(s) | Min(s)
===========================================================================================================
          :: | time                   |     1 |     1 | 91.690 | 91.690 | 91.690 | 91.690 | 91.690 | 91.690
      ::http | geturl                 |  1000 |  1000 | 91.662 | 91.662 |  0.092 |  0.092 |  0.280 |  0.086
      ::http | wait                   |  1000 |  1000 | 66.052 | 66.052 |  0.066 |  0.066 |  0.255 |  0.061
          :: | vwait                  |  1000 |  1000 | 66.024 | 66.024 |  0.066 |  0.066 |  0.255 |  0.061
          :: | eval                   |  1000 |  1000 | 25.082 | 25.082 |  0.025 |  0.025 |  0.071 |  0.023
             | ::socket               |  1000 |  1000 | 25.066 | 25.066 |  0.025 |  0.025 |  0.071 |  0.023
      ::http | Event                  | 13000 | 13000 |  1.279 |  1.279 |  0.000 |  0.000 |  0.002 |  0.000
          :: | regexp                 | 18002 | 18002 |  0.266 |  0.266 |  0.000 |  0.000 |  0.001 |  0.000
      ::http | Eof                    |  1000 |  1000 |  0.243 |  0.243 |  0.000 |  0.000 |  0.001 |  0.000
          :: | gets                   | 12003 | 12003 |  0.228 |  0.228 |  0.000 |  0.000 |  0.001 |  0.000
          :: | flush                  |  1000 |  1000 |  0.203 |  0.203 |  0.000 |  0.000 |  0.001 |  0.000
          :: | read                   |  1003 |  1003 |  0.194 |  0.194 |  0.000 |  0.000 |  0.001 |  0.000
      ::http | Finish                 |  2000 |  2000 |  0.174 |  0.174 |  0.000 |  0.000 |  0.001 |  0.000
      ::http | CloseSocket            |  1000 |  1000 |  0.152 |  0.152 |  0.000 |  0.000 |  0.001 |  0.000
          :: | close                  |  1003 |  1003 |  0.133 |  0.133 |  0.000 |  0.000 |  0.001 |  0.000
          :: | string                 | 28064 | 28064 |  0.113 |  0.113 |  0.000 |  0.000 |  0.000 |  0.000
          :: | variable               | 23008 | 23008 |  0.066 |  0.066 |  0.000 |  0.000 |  0.000 |  0.000
      ::http | reset                  |  1000 |  1000 |  0.039 |  0.039 |  0.000 |  0.000 |  0.000 |  0.000
      ::http | CharsetToEncoding      |  1000 |  1000 |  0.037 |  0.037 |  0.000 |  0.000 |  0.000 |  0.000
::tcl::clock | _loader                |     1 |     1 |  0.021 |  0.021 |  0.021 |  0.021 |  0.021 |  0.021
          :: | source                 |     1 |     3 |  0.019 |  0.004 |  0.019 |  0.002 |  0.019 |  0.000
             | ::tcl::string::map     |  2013 |  2013 |  0.018 |  0.018 |  0.000 |  0.000 |  0.000 |  0.000
      ::http | cleanup                |  1000 |  1000 |  0.016 |  0.016 |  0.000 |  0.000 |  0.000 |  0.000
             | ::tcl::string::tolower | 13038 | 13038 |  0.015 |  0.015 |  0.000 |  0.000 |  0.000 |  0.000
          :: | lappend                | 10011 | 10011 |  0.013 |  0.013 |  0.000 |  0.000 |  0.000 |  0.000
          :: | join                   |  2000 |  2000 |  0.013 |  0.013 |  0.000 |  0.000 |  0.000 |  0.000
          :: | eof                    | 13000 | 13000 |  0.012 |  0.012 |  0.000 |  0.000 |  0.000 |  0.000
          :: | if                     |     4 |    16 |  0.012 |  0.011 |  0.003 |  0.001 |  0.005 |  0.000
             | ::tcl::string::trim    | 13008 | 13008 |  0.012 |  0.012 |  0.000 |  0.000 |  0.000 |  0.000
          :: | namespace              |  1010 |  1027 |  0.012 |  0.002 |  0.000 |  0.000 |  0.005 |  0.000
          :: | unset                  |  2005 |  2005 |  0.011 |  0.011 |  0.000 |  0.000 |  0.000 |  0.000
          :: | fconfigure             |  3000 |  3000 |  0.010 |  0.010 |  0.000 |  0.000 |  0.000 |  0.000
          :: | lsort                  |  1000 |  1000 |  0.010 |  0.010 |  0.000 |  0.000 |  0.000 |  0.000

That was profiler-output for the following code, that additionally filtered functions by total time < 10ms:

time {
  set h [http::geturl "http://$url/"]
  http::data $h
  http::cleanup $h
} 1000

It is extremely configurable, so e. g. I can output calling arguments also for commands with time over N ms, for example to see slowly SQL statements on prepare or execute, etc.

About the code coverage mode: it is extremely integrated with my tclSE-mod (my own fork of tcl). I don't believe, that I could easy port it to original tcl.core, without modifying of it.

sebres commented 7 years ago

If someone would like to read a bit about abovementioned tclSE, here yet a short description why and how I wrote tclSE...

lehenbauer commented 7 years ago

We want it to be open source. We want to be able to set breakpoints and step through a function. We'd like to be able to require some package or something that would allow us to connect to a running Tcl program and start debugging it. For instance, mod_rivet adds a Tcl interpreter to Apaache. We'd like to be able to get into the debugger to debug the interpreter when it fetches a certain page.

sebres commented 7 years ago

I've all that... (except "some package or something that would allow us to connect to a running Tcl program"). That is currently realized as tcl-command (debug on or debug orient) inside tcl-debugger, that should be called in yours servlet runner (or across rivet binding)... In my sublime binding it calls a configured URL to my tcl-server (nginx-fcgi-module) to attach remote debugging, where following scenario is possible:

# attach/detach debugger URL-proc:
proc /debug/ {} {
   # start / stop remote debugging:
   if {[getargv on "off"]} { 
     debug configure -remote [getargv host]:[getargv port] 
     debug on
   } else {
     debug off
   }
}
...
proc url-mapper {...} {
   # check debugger was on ....
   debug orient
   # call url-mapped command:
   /$uri/
}

My current problem is - I've no GUI (only debugger tcl-module resp. library). So it should be then integrated in something other as SublimeText (because of "we want it to be open source."). Any suggestions? Best if such IDE or editor are expandable with own modules... (but please no eclipse and co. ;) It should be script-able or at least C/C++/C#.

lehenbauer commented 7 years ago

A GUI would be really nice but if it worked similarly to gdb I think we could live with it.

sebres commented 7 years ago

Understood. I'll see what I can do here after finishing of clock speed-up (#4).

blacksqr commented 7 years ago

If you don't mind me putting in my 2¢ worth, and not to discourage sebres, but it sounds like ramdebugger already has many of the described features. It can debug remotely, has a gui, and can act as a gdb front end to boot.

Maybe ramdebugger could be used as a starting point for a package that meets all requirements.

P.S. I'd really be interested to see a version of the sublime integration code that works with vanilla Tcl.

sebres commented 7 years ago

Maybe ramdebugger could be used

Possibly as GUI basis... Because as debugger it is IMHO not really suitable (at least it was so, as I touch it last time many years ago). Apart from the only older version support (I think it was 8.4 or even 8.3 only). But as idea for GUI... must take a look, Thanks.

P.S. I'd really be interested to see a version of the sublime integration code that works with vanilla Tcl.

Unfortunately I develop several years not with vanilla Tcl. Always missing time for dressing of the source code of my fork. It's still worse because my SublimeText (resp. this intergration) works not with vanilla python (I'm a really hacker ;)

sebres commented 7 years ago

Close as not interested