Changing the List Elements in a List Widget Crashes VM

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Changing the List Elements in a List Widget Crashes VM

David Finlayson-4
I am trying to build a GUI that queues up a list of files that need to
be processed (I'll try to attach a small picture here, if the list
accepts attachments). I have added a button 'Add' that when clicked,
calls the method #addFiles shown here:

addFiles
       | dialog fileSet |
       dialog := MultiOpenFileDialog new.
       dialog
               windowTitle: 'Select Files To Process';
               defaultDirectory: workingDirectory.
       dialog open
               ifTrue: [fileSet := filesToProcess list asSet. "Set prevents
duplicates filenames"
                       fileSet addAll: (dialog selectionStrings).
                       filesToProcess list: (fileSet asList sorted).
"Sorted order seems
better than random"
                       workingDirectory := (fileSet asList at: 1)
asFilename directory]

What is supposed to happen is the user selects a bunch of files and I
add them to the list of files already in displayed in the List widget.
This works for the first couple of clicks, but after clicking on the
add button a few times, it always crashes the virtual machine.
(Totally bombs out of VisualWorks). Why? What am I doing wrong here?

#filesToProcess returns a MultiSelectionInList used by the List widget.

--
David Finlayson

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

window.png (53K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

Andres Valloud-6
At first glance, if MultiOpenFileDialog useWin32NativeDialogs answers
true.  While it's really hard to tell what's going on, can you try
turning off useWin32NativeDialogs?  If it doesn't crash without native
dialogs, then I'd suspect native dialogs have some bug where the
handling of the native API is not totally correct.

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of David Finlayson
Sent: Wednesday, March 31, 2010 1:17 PM
To: [hidden email]
Subject: [vwnc] Changing the List Elements in a List Widget Crashes VM

I am trying to build a GUI that queues up a list of files that need to
be processed (I'll try to attach a small picture here, if the list
accepts attachments). I have added a button 'Add' that when clicked,
calls the method #addFiles shown here:

addFiles
       | dialog fileSet |
       dialog := MultiOpenFileDialog new.
       dialog
               windowTitle: 'Select Files To Process';
               defaultDirectory: workingDirectory.
       dialog open
               ifTrue: [fileSet := filesToProcess list asSet. "Set
prevents duplicates filenames"
                       fileSet addAll: (dialog selectionStrings).
                       filesToProcess list: (fileSet asList sorted).
"Sorted order seems
better than random"
                       workingDirectory := (fileSet asList at: 1)
asFilename directory]

What is supposed to happen is the user selects a bunch of files and I
add them to the list of files already in displayed in the List widget.
This works for the first couple of clicks, but after clicking on the add
button a few times, it always crashes the virtual machine.
(Totally bombs out of VisualWorks). Why? What am I doing wrong here?

#filesToProcess returns a MultiSelectionInList used by the List widget.

--
David Finlayson

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

David Finlayson
Thanks! There seems to be a bug in the native dialog there. I issued:

Dialog useNativeDialogs: false

and relaunched the application. So far it hasn't crashed.

Is this a known bug?

--
David Finlayson
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

Andres Valloud-6
Well, apparently it is :(.  Can you provide us more information as to
what location the file dialog is opening on, any arguments passed in,
etc?  It would be great to reproduce the problem here.

-----Original Message-----
From: David Finlayson [mailto:[hidden email]]
Sent: Wednesday, March 31, 2010 2:39 PM
To: Valloud, Andres
Cc: VWNC,
Subject: Re: [vwnc] Changing the List Elements in a List Widget Crashes
VM

Thanks! There seems to be a bug in the native dialog there. I issued:

Dialog useNativeDialogs: false

and relaunched the application. So far it hasn't crashed.

Is this a known bug?

--
David Finlayson

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

Andres Valloud-6
In reply to this post by David Finlayson
Also, which version of VW are you using?

-----Original Message-----
From: David Finlayson [mailto:[hidden email]]
Sent: Wednesday, March 31, 2010 2:39 PM
To: Valloud, Andres
Cc: VWNC,
Subject: Re: [vwnc] Changing the List Elements in a List Widget Crashes
VM

Thanks! There seems to be a bug in the native dialog there. I issued:

Dialog useNativeDialogs: false

and relaunched the application. So far it hasn't crashed.

Is this a known bug?

--
David Finlayson

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

David Finlayson
Version: VisualWorks® NonCommercial, 7.7 of December 15, 2009
Running on Windows XP

You can reproduce the problem with this code in a workspace on both
windows XP and windows 7:

" Create a directory with a lot of files (more than 255 will do it for sure)"
tempDir := 'temp' asFilename.
tempDir makeDirectory.
1 to: 300 do: [ :i |
        tempFile := ('temp\temp_', i printString) asFilename.
        stream := tempFile writeStream.
        stream close.]

" Try to reading in every file in the directory - no problem with VW
MultiOpenFileDialog. I've tested it on hundreds of files."
Dialog useNativeDialogs: false.
list := List new.
dialog := MultiOpenFileDialog new.
dialog
        windowTitle: 'Select Files To Process';
        defaultDirectory: tempDir.
dialog open
        ifTrue: [list addAll: (dialog selectionStrings)].

"Now try to read in a bunch of files (> 50) with Native
MultiOpenFileDialog (this WILL crash eventually). You may need to do
this 2 or 3 times before you get the crash. Selecting all files in the
directory crashes every time. This may be a 255 file limit of the
native dialog. I've seen this bug before in C++ programs. There is a
work-around."

Dialog useNativeDialogs: true.
list := List new.
dialog := MultiOpenFileDialog new.
dialog
        windowTitle: 'Select Files To Process';
        defaultDirectory: tempDir.
dialog open
        ifTrue: [list addAll: (dialog selectionStrings)].

Hope that helps.

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

Andres Valloud-6
David, thank you for this most useful code.  I tried it in one of our
recent next release builds, and I could not reproduce the crash.
Instead, I get a FNERR_BUFFERTOOSMALL error.  However, I do see a
potential problem.  The function called is a Unicode function, and the
MSDN docs state that in that case, the struct passed in to
GetOpenFileNameW must have a buffer and a buffer size specified in
TCHARS.  For Unicode, each TCHAR is 2 bytes long.  So there is this
method called fileNameBufferSize, which answers 1024.  If you check
senders, you will see that

initializeFor: aCommdlgInterface

        | empty |
        interface := aCommdlgInterface.
        ofn := aCommdlgInterface OPENFILENAME gcMalloc.
        filename := CIntegerType unsignedChar gcMalloc: self
fileNameBufferSize.
        empty := interface encodeWide: ''. "Null terminated
empty string"
        filename copyAt: 0 from: empty size: empty size startingAt: 1.
        ofn
                zeroFill;
                memberAt: #lStructSize put: ofn type referentType
sizeof;
                memberAt: #lpstrFile put: filename;
                memberAt: #nMaxFile put: self fileNameBufferSize.
        self setFlag: interface OFN_EXPLORER.
        interface CoInitialize: nil.
        self initialDirectory:  Filename defaultDirectory asString

creates a filename buffer 1024 *BYTES* long (because unsignedChar is not
a TCHAR).  Consequently, Windows will think the buffer can hold 1024
TCHARS, which in Unicode requires 2048 bytes.  Unfortunately there's not
enough memory reserved in the filename buffer, so you have a buffer
overflow condition.  I think I must have gotten FNERR_BUFFERTOOSMALL
because the answer was larger than 1024 TCHARS.  However, in the cases
you describe, it seems possible to get an answer between 1024 and 2048
bytes which should result in undefined behavior.

I have not thoroughly verified this problem, but I am very suspicious
this analysis leads to potential trouble that needs to be checked out.
At first glance, it looks like the buffer should be allocated in terms
of unsigned shorts, as opposed to unsigned chars.  Thank you for letting
us know.  AR 59745.

Andres.

-----Original Message-----
From: David Finlayson [mailto:[hidden email]]
Sent: Wednesday, March 31, 2010 9:39 PM
To: Valloud, Andres
Cc: VWNC,
Subject: Re: [vwnc] Changing the List Elements in a List Widget Crashes
VM

Version: VisualWorks(r) NonCommercial, 7.7 of December 15, 2009 Running
on Windows XP

You can reproduce the problem with this code in a workspace on both
windows XP and windows 7:

" Create a directory with a lot of files (more than 255 will do it for
sure)"
tempDir := 'temp' asFilename.
tempDir makeDirectory.
1 to: 300 do: [ :i |
        tempFile := ('temp\temp_', i printString) asFilename.
        stream := tempFile writeStream.
        stream close.]

" Try to reading in every file in the directory - no problem with VW
MultiOpenFileDialog. I've tested it on hundreds of files."
Dialog useNativeDialogs: false.
list := List new.
dialog := MultiOpenFileDialog new.
dialog
        windowTitle: 'Select Files To Process';
        defaultDirectory: tempDir.
dialog open
        ifTrue: [list addAll: (dialog selectionStrings)].

"Now try to read in a bunch of files (> 50) with Native
MultiOpenFileDialog (this WILL crash eventually). You may need to do
this 2 or 3 times before you get the crash. Selecting all files in the
directory crashes every time. This may be a 255 file limit of the native
dialog. I've seen this bug before in C++ programs. There is a
work-around."

Dialog useNativeDialogs: true.
list := List new.
dialog := MultiOpenFileDialog new.
dialog
        windowTitle: 'Select Files To Process';
        defaultDirectory: tempDir.
dialog open
        ifTrue: [list addAll: (dialog selectionStrings)].

Hope that helps.

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

Andres Valloud-6
Just out of curiosity, does replacing unsignedChar with unsignedShort in
the below initializeFor: method solve the problem for you?

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On
Behalf Of Valloud, Andres
Sent: Wednesday, March 31, 2010 10:27 PM
To: David Finlayson
Cc: VWNC,
Subject: Re: [vwnc] Changing the List Elements in a List Widget Crashes
VM

David, thank you for this most useful code.  I tried it in one of our
recent next release builds, and I could not reproduce the crash.
Instead, I get a FNERR_BUFFERTOOSMALL error.  However, I do see a
potential problem.  The function called is a Unicode function, and the
MSDN docs state that in that case, the struct passed in to
GetOpenFileNameW must have a buffer and a buffer size specified in
TCHARS.  For Unicode, each TCHAR is 2 bytes long.  So there is this
method called fileNameBufferSize, which answers 1024.  If you check
senders, you will see that

initializeFor: aCommdlgInterface

        | empty |
        interface := aCommdlgInterface.
        ofn := aCommdlgInterface OPENFILENAME gcMalloc.
        filename := CIntegerType unsignedChar gcMalloc: self
fileNameBufferSize.
        empty := interface encodeWide: ''. "Null terminated
empty string"
        filename copyAt: 0 from: empty size: empty size startingAt: 1.
        ofn
                zeroFill;
                memberAt: #lStructSize put: ofn type referentType
sizeof;
                memberAt: #lpstrFile put: filename;
                memberAt: #nMaxFile put: self fileNameBufferSize.
        self setFlag: interface OFN_EXPLORER.
        interface CoInitialize: nil.
        self initialDirectory:  Filename defaultDirectory asString

creates a filename buffer 1024 *BYTES* long (because unsignedChar is not
a TCHAR).  Consequently, Windows will think the buffer can hold 1024
TCHARS, which in Unicode requires 2048 bytes.  Unfortunately there's not
enough memory reserved in the filename buffer, so you have a buffer
overflow condition.  I think I must have gotten FNERR_BUFFERTOOSMALL
because the answer was larger than 1024 TCHARS.  However, in the cases
you describe, it seems possible to get an answer between 1024 and 2048
bytes which should result in undefined behavior.

I have not thoroughly verified this problem, but I am very suspicious
this analysis leads to potential trouble that needs to be checked out.
At first glance, it looks like the buffer should be allocated in terms
of unsigned shorts, as opposed to unsigned chars.  Thank you for letting
us know.  AR 59745.

Andres.

-----Original Message-----
From: David Finlayson [mailto:[hidden email]]
Sent: Wednesday, March 31, 2010 9:39 PM
To: Valloud, Andres
Cc: VWNC,
Subject: Re: [vwnc] Changing the List Elements in a List Widget Crashes
VM

Version: VisualWorks(r) NonCommercial, 7.7 of December 15, 2009 Running
on Windows XP

You can reproduce the problem with this code in a workspace on both
windows XP and windows 7:

" Create a directory with a lot of files (more than 255 will do it for
sure)"
tempDir := 'temp' asFilename.
tempDir makeDirectory.
1 to: 300 do: [ :i |
        tempFile := ('temp\temp_', i printString) asFilename.
        stream := tempFile writeStream.
        stream close.]

" Try to reading in every file in the directory - no problem with VW
MultiOpenFileDialog. I've tested it on hundreds of files."
Dialog useNativeDialogs: false.
list := List new.
dialog := MultiOpenFileDialog new.
dialog
        windowTitle: 'Select Files To Process';
        defaultDirectory: tempDir.
dialog open
        ifTrue: [list addAll: (dialog selectionStrings)].

"Now try to read in a bunch of files (> 50) with Native
MultiOpenFileDialog (this WILL crash eventually). You may need to do
this 2 or 3 times before you get the crash. Selecting all files in the
directory crashes every time. This may be a 255 file limit of the native
dialog. I've seen this bug before in C++ programs. There is a
work-around."

Dialog useNativeDialogs: true.
list := List new.
dialog := MultiOpenFileDialog new.
dialog
        windowTitle: 'Select Files To Process';
        defaultDirectory: tempDir.
dialog open
        ifTrue: [list addAll: (dialog selectionStrings)].

Hope that helps.

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

Christian Haider
In reply to this post by David Finlayson
Hi,

I ran into the same problem (too many files selected in a native windows file selection dialog - how dare they :-) and fixed it with the attached code. I didnt see any crashes thou...

Usage:

        | dialog |
        dialog := FileDialogWin32Surrogate forOpenMultiFileDialog.
        dialog
                windowTitle: (#titleOpenChartFiles << #smallCharts >> 'Öffne Chartdateien') asString;
                addFileFilter: #pdfFilesLabel << #smallCharts >> 'PDF Dateien (*.pdf)' pattern: '*.pdf';
                addFileFilter: #csvFilesLabel << #smallCharts >> 'Komma separierte Dateien (*.csv)'
                        pattern: '*.csv';
                addFileFilter: #textFilesLabel << #smallCharts >> 'Textdateien (*.txt)' pattern: '*.txt';
                addFileFilter: #allFilesLabel << #smallCharts >> 'Alle Dateien (*.*)' pattern: '*.*';
                defaultFilename: '*', self defaultFileExtension;
                defaultDirectory: self lastDirectoryForSave;
                fileCondition: #multipleOld;
                setCallbackForMultiselect.
        ^dialog select

HTH,
        Christian


> -----Ursprüngliche Nachricht-----
> Von: [hidden email]
> [mailto:[hidden email]] Im Auftrag von Valloud, Andres
> Gesendet: Donnerstag, 1. April 2010 07:46
> An: David Finlayson
> Cc: VWNC,
> Betreff: Re: [vwnc] Changing the List Elements in a List
> Widget Crashes VM
>
> David, thank you for this most useful code.  I tried it in one of our
> recent next release builds, and I could not reproduce the crash.
> Instead, I get a FNERR_BUFFERTOOSMALL error.  However, I do see a
> potential problem.  The function called is a Unicode function, and the
> MSDN docs state that in that case, the struct passed in to
> GetOpenFileNameW must have a buffer and a buffer size specified in
> TCHARS.  For Unicode, each TCHAR is 2 bytes long.  So there is this
> method called fileNameBufferSize, which answers 1024.  If you check
> senders, you will see that
>
> initializeFor: aCommdlgInterface
>
> | empty |
> interface := aCommdlgInterface.
> ofn := aCommdlgInterface OPENFILENAME gcMalloc.
> filename := CIntegerType unsignedChar gcMalloc: self
> fileNameBufferSize.
> empty := interface encodeWide: ''. "Null terminated
> empty string"
> filename copyAt: 0 from: empty size: empty size startingAt: 1.
> ofn
> zeroFill;
> memberAt: #lStructSize put: ofn type referentType
> sizeof;
> memberAt: #lpstrFile put: filename;
> memberAt: #nMaxFile put: self fileNameBufferSize.
> self setFlag: interface OFN_EXPLORER.
> interface CoInitialize: nil.
> self initialDirectory:  Filename defaultDirectory asString
>
> creates a filename buffer 1024 *BYTES* long (because
> unsignedChar is not
> a TCHAR).  Consequently, Windows will think the buffer can hold 1024
> TCHARS, which in Unicode requires 2048 bytes.  Unfortunately
> there's not
> enough memory reserved in the filename buffer, so you have a buffer
> overflow condition.  I think I must have gotten FNERR_BUFFERTOOSMALL
> because the answer was larger than 1024 TCHARS.  However, in the cases
> you describe, it seems possible to get an answer between 1024 and 2048
> bytes which should result in undefined behavior.
>
> I have not thoroughly verified this problem, but I am very suspicious
> this analysis leads to potential trouble that needs to be checked out.
> At first glance, it looks like the buffer should be allocated in terms
> of unsigned shorts, as opposed to unsigned chars.  Thank you
> for letting
> us know.  AR 59745.
>
> Andres.
>
> -----Original Message-----
> From: David Finlayson [mailto:[hidden email]]
> Sent: Wednesday, March 31, 2010 9:39 PM
> To: Valloud, Andres
> Cc: VWNC,
> Subject: Re: [vwnc] Changing the List Elements in a List
> Widget Crashes
> VM
>
> Version: VisualWorks(r) NonCommercial, 7.7 of December 15,
> 2009 Running
> on Windows XP
>
> You can reproduce the problem with this code in a workspace on both
> windows XP and windows 7:
>
> " Create a directory with a lot of files (more than 255 will do it for
> sure)"
> tempDir := 'temp' asFilename.
> tempDir makeDirectory.
> 1 to: 300 do: [ :i |
> tempFile := ('temp\temp_', i printString) asFilename.
> stream := tempFile writeStream.
> stream close.]
>
> " Try to reading in every file in the directory - no problem with VW
> MultiOpenFileDialog. I've tested it on hundreds of files."
> Dialog useNativeDialogs: false.
> list := List new.
> dialog := MultiOpenFileDialog new.
> dialog
> windowTitle: 'Select Files To Process';
> defaultDirectory: tempDir.
> dialog open
> ifTrue: [list addAll: (dialog selectionStrings)].
>
> "Now try to read in a bunch of files (> 50) with Native
> MultiOpenFileDialog (this WILL crash eventually). You may need to do
> this 2 or 3 times before you get the crash. Selecting all files in the
> directory crashes every time. This may be a 255 file limit of
> the native
> dialog. I've seen this bug before in C++ programs. There is a
> work-around."
>
> Dialog useNativeDialogs: true.
> list := List new.
> dialog := MultiOpenFileDialog new.
> dialog
> windowTitle: 'Select Files To Process';
> defaultDirectory: tempDir.
> dialog open
> ifTrue: [list addAll: (dialog selectionStrings)].
>
> Hope that helps.
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>
>
>
>

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

OpenMultiFilenameRequest.st (5K) Download Attachment
FileDialogWin32Surrogate-initializeOpenMultiFileName.st (1K) Download Attachment
FileDialogWin32Surrogate class-forOpenMultiFileDialog.st (624 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

David Finlayson
In reply to this post by Andres Valloud-6
It changes the problem(s):

1. I didn't see the whole VM crash, so maybe the undefined behavior
problem is fixed.

2. You still can only select <255 files or you get that
FNERR_BUFFERTOOSMALL error.

3. The change mangled actual file names returned.

Instead of files like temp_1, temp_2, temp_3, etc.
I got: p_1, p_2, p_3 and the last filename returned was just Unicode
goop (UniGoop??). See the attached image.

Switching back to unsignedChar fixed the file name mangling but the
random crashes returned also.

I haven't tried Christian's suggestion (I am a novice at VW and I need
to digest what Christian's code is doing differently).

David

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

window_withShort.png (67K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Changing the List Elements in a List Widget Crashes VM

David Finlayson
Actually, #2 below is <<255, I assume that it is the total length of
the filenames returned that is the limit, rather than simply the
number of filenames per se.

On Thu, Apr 1, 2010 at 4:10 PM, David Finlayson
<[hidden email]> wrote:

> It changes the problem(s):
>
> 1. I didn't see the whole VM crash, so maybe the undefined behavior
> problem is fixed.
>
> 2. You still can only select <255 files or you get that
> FNERR_BUFFERTOOSMALL error.
>
> 3. The change mangled actual file names returned.
>
> Instead of files like temp_1, temp_2, temp_3, etc.
> I got: p_1, p_2, p_3 and the last filename returned was just Unicode
> goop (UniGoop??). See the attached image.
>
> Switching back to unsignedChar fixed the file name mangling but the
> random crashes returned also.
>
> I haven't tried Christian's suggestion (I am a novice at VW and I need
> to digest what Christian's code is doing differently).
>
> David
>



--
David Finlayson, Ph.D.
Operational Geologist

U.S. Geological Survey
Pacific Science Center
400 Natural Bridges Drive
Santa Cruz, CA  95060, USA

Phone: (831) 704-6547
E-mail: [hidden email]
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc