Blender Python GUI: weird segmentation faults


(amorilia) #1

I am designing a GUI for an export script and I get segmentation faults. The script below reproduces the problem. What is weird is that the script may run fine for a few times: it does not immediately lead to segfaults. If I repeatedly run the script (loading it into the text window and running it via ALT-P), I usually get a segfault around the 10’th trial. Does someone see what is wrong with the code?

The problem occurs on both v237 and the alpha release (releaseblender-2.40alpha1-linux-glibc232-py23-i386), linux platform.


import Blender
from Blender import BGL
from Blender import Draw

last_exported = 'test.nif'
force_dds = 0
strip_texpath = 0
scale_correction = 10.0

# Export

def export_nif(filename):
    print "exporting..."
    print "%f %i %s %s"%(scale_correction,force_dds,strip_texpath,last_exported)

# GUI

evtExport   = 1
evtBrowse   = 2
evtForceDDS = 3
evtSTexPath = 4
evtScale    = 5
evtFilename = 6
evtCancel   = 7

bFilename = Draw.Create(last_exported)
bForceDDS = Draw.Create(force_dds)
bSTexPath = Draw.Create(strip_texpath)
bScale    = Draw.Create(scale_correction)

def gui():
    global bFilename, bForceDDS, bSTexPath, bScale

    BGL.glClearColor(0.753, 0.753, 0.753, 0.0)
    BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)

    Draw.Button('Cancel', evtCancel, 208, 8, 71, 23, 'Cancel the export script.')
    Draw.Button('Export NIF', evtExport, 8, 8, 87, 23, 'Export the NIF file with these settings.')
    Draw.Button('Browse', evtBrowse, 8, 48, 55, 23, 'Browse folders and select an other filename.')
    bFilename = Draw.String('', evtFilename, 72, 48, 207, 23, bFilename.val, 512, 'Filename of the NIF file to be written. If there is animation, also x***.nif and x***.kf files will be written.')
    bForceDDS = Draw.Toggle('Force DDS', evtForceDDS, 8, 80, 127, 23, bForceDDS.val, 'Force textures to be exported with a .DDS extension? Usually, you can leave this disabled.')
    bSTexPath = Draw.Toggle('Strip Texture Path', evtSTexPath, 152, 80, 127, 23, bSTexPath.val, "Strip texture path in NIF file. You should leave this disabled, especially when this model's textures are stored in a subdirectory of the Data Files\Textures folder.")
    bScale = Draw.Slider('Scale Correction: ', evtScale, 8, 112, 271, 23, bScale.val, 0.01, 100, 0, 'How many NIF units is one Blender unit?')

def event(evt, val):
    if (evt == Draw.QKEY and not val):
        Draw.Exit()
    
def select(filename):
    global bFilename
    bFilename.val = filename

def bevent(evt):
    global scale_correction,force_dds,strip_texpath,last_exported

    if evt == evtBrowse:
        Blender.Window.FileSelector(select, 'Select')
        Draw.Redraw(1)
    elif evt == evtExport:
        # Read out values.
        force_dds = bForceDDS.val
        strip_texpath = bSTexPath.val
        scale_correction = bScale.val
        last_exported = bFilename.val
        # Stop GUI.
        Draw.Exit()
        # Export NIF file.
        export_nif(last_exported)
    elif evt == evtCancel:
        Draw.Exit()

Draw.Register(gui, event, bevent)


(wah_tak) #2

Well, segfaults actually shouldn’t happen at all when scripting, so probably it’s a bug in the API.
But possibly that bug only shows when you do something wrong in your Python script. So it may, or may not be an error in your script.

You just have to slowly delete certain parts of your script and check whether the error still occurs. Of course it is very fustrating if the problem is not really reproducable.

Else i’m sorry, but i can’t help.
At least i can confirm that i also got a crash at about the 25th run.


(amorilia) #3

Thanks wah_tak! I removed as many lines as possible, and I can reproduce the bug with the code below. It is very weird, but doing really trivial things such as removing tooltips, removing another button, removing the assignments in bevent, … and the segfault does not occur anymore (running the script at least 25 times).

Should I file a bug report for this? (Never done that before :expressionless: )


import Blender
from Blender import Draw

last_exported = 'test.nif'
scale_correction = 10.0

# GUI

evtExport   = 1
evtScale    = 5
evtFilename = 6

bFilename = Draw.Create(last_exported)
bScale    = Draw.Create(scale_correction)

def gui():
    global bFilename, bScale

    Draw.Button('Export NIF', evtExport, 8, 8, 87, 23, '')
    bFilename = Draw.String('', evtFilename, 72, 48, 207, 23, bFilename.val, 512, '')
    bScale = Draw.Slider('Scale Correction: ', evtScale, 8, 112, 271, 23, bScale.val, 0.01, 100, 0, '')

def bevent(evt):
    global scale_correction, last_exported

    if (evt == evtExport):
        # Read out values.
        scale_correction = bScale.val
        last_exported = bFilename.val
        # Stop GUI	    
        Draw.Exit()

Draw.Register(gui, None, bevent)