[plt-scheme] how to determine where a thread hangs?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Apr 17 22:03:15 EDT 2009

At Fri, 17 Apr 2009 18:33:12 -0700, YC wrote:
> what are some approaches to determine where in code the thread execution (or
> multiple threads) hangs?

Here's a function that creates a thread to watch a different thread.
Every `delay' seconds, it grabs a stack trace of the thread `t':

 (define (watch-thread t delay)
   ;; create a new thread to report snapshots of t:
   (thread (lambda ()
             (let loop ()
               (sleep delay)
               (let ([trace (continuation-mark-set->context 
                             (continuation-marks t))])
                 (unless (null? trace)
                    (for-each print-location trace)

Maybe something like that would help you.

Here's a basic print-location function to use with watch-thread:

 (define (print-location i)
   (let ([id (car i)]
         [src (cdr i)])
      [src (printf "~a:~a~a\n"
                   (srcloc-source src)
                   (if (srcloc-line src)
                       (format "~a:~a" 
                               (srcloc-line src)
                               (srcloc-column src))
                       (srcloc-position src))
                   (if id
                       (format ": ~a" id)
      [id (printf "~a\n" id)]
      [else (printf "???\n")])))

For example, the following shows where all the time goes when you load
the implementation of the main PLT Scheme reference:

  (let ([watcher-t (watch-thread (current-thread) 0.1)])
    (dynamic-require '(lib "scribblings/reference/reference.scrbl") #f)
    (kill-thread watcher-t))

This is a noisy way to monitor a thread, though. Instead of dumping each
stack trace, you might just save it to check later when the thread
seems to be stuck.

The gprof-like profiler that Eli mentioned on plt-dev works in a
similar way:


Posted on the users mailing list.