Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non blocking pyplot GUI for GDB python pretty printer

I just want to use matplotlib to visualize some data when debugging. Follow this page: Analyzing C/C++ matrix in the gdb debugger with Python and Numpy - CodeProject, it works OK unless the matplotlib GUI just block the GDB's command line. Which means if I leave the GUI window open, the GDB's command line is freezed, and I can't enter anything in the GDB command until I close the pyplot window.

To solve this, I just try to run the plotting code in another thread, to simplify the test case, I just create a simple python source code named "test-pyplot.py" with the contents below

import numpy as np
from matplotlib import pyplot as plt
from threading import Thread

class MyThread (Thread):

    def __init__(self, thread_id):
        Thread.__init__(self)
        self.thread_id = thread_id

    def run(self):
        x = np.arange(0, 5, 0.1);
        y = np.sin(x)
        plt.plot(x, y)
        plt.show(block = True) #this cause the mainloop

thread1 = MyThread(1)
thread1.start()

Now, under the GDB command line, I simply type: source test-pyplot.py, and a non blocking GUI will open and it looks good, that GDB's command line can still accept command, so far so good.

But the problem happens when I close the plot window, then I run the source test-pyplot.py again, this time, GDB just hangs.

I'm using python 2.7.6 under Windows, and I see that matplotlib was default to use the tkAgg as the drawing back end, so I try to see whether this will happen for a normal tk GUI window. Here is another test python file named "test-tk.py", which has contents below:

from Tkinter import *
from threading import Thread
class App():
    def __init__(self):
        self.g=Tk()
        self.th=Thread(target=self.g.mainloop)
        self.th.start()
    def destroy(self):
        self.g.destroy()
a1 = App()

If I run the command source test-tk.py under GDB prompt, a tk window will show up, GDB is still alive(not freezed), and I can close the tk window, and type the command source test-tk.py again, and every thing works fine, GDB does not hang. I can even run the command source test-tk.py twice without close the first tk window, then there will be two tk window shown.

Question: how to correctly show matplotlib pyplot figure in non-blocking mode, which don't hang GDB? Thanks. Normally, plt.show will internally call the mainloop function of the Tkinter package, which is a event loop. matplotlib do have an option named interactive mode, which can be enabled by calling the `plt.ion()', but it don't solve my problem.

like image 478
ollydbg23 Avatar asked Nov 21 '25 00:11

ollydbg23


1 Answers

There's multiple issues. And FWIW I think I looked into this exact issue once before, search gdb bugzilla.

Anyway, one issue is that you should probably run the GUI in a separate thread. This avoids the lack of main-loop integration. This is a bit tougher to program, though you can use Python tricks to make it less painful.

Also, GUI toolkits typically mess with SIGCHLD, which breaks gdb. So you have to use a hack to deal with this.

You can see how I dealt with these problems in my proof-of-concept gdb GUI: https://gitorious.org/gdb-gui

like image 102
Tom Tromey Avatar answered Nov 23 '25 14:11

Tom Tromey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!