Vista X64 GDI+ and System.Drawing errors

G

Guest

I have an application that I have used for years on 32-bit XP. It also
appears to run properly on 32-bit Vista - at least I haven't had any users
complain.

When I try to run the app on Vista X64, I get errors randomly in
System.Drawing and GDI+ when I call Image.FromStream(Stream).

If the System.Drawing exception occurs, it is an ArgumentException and the
message is "Parameter is not valid." The stack trace provides this
information:

at System.Drawing.Image.FromStream(Stream stream, Boolean
useEmbeddedColorManagement, Boolean validateImageData)\r\n at
System.Drawing.Image.FromStream(Stream stream)

It appears to be an internal error in System.Drawing - or GDI+ that
System.Drawing is not passing on unchanged so I can't tell.

If the GDI+ error occurs, the exception is of type
System.Runtime.InteropServices.ExternalException. The error message says "A
generic error occurred in GDI+." The stack trace shows the same message as
above for the System.Drawing exception.

I get either one or the other, I don't get both in the same instance.

I create a MemoryStream in a BackgroundWorker thread with this code:

MemoryStream imageStream = null;

if (files.Length > 0 && File.Exists(picturePath))
{
imageStream = GetImageStream(picturePath);
}


That stream is passed to the BackgroundWorker's ProgressChanged event as a
property of a custom class passed in the UserState object of the
ProgressChangedEventArgs and converted to an image with:

Image mg = null;

try
{
mg = Image.FromStream(p.PictureData);
}
catch(Exception ex)
{
MessageBox.Show("Cannot create image for " +
p.Mp3FileName + "\r\n" + "Exception: " + ex.Message);
}


where p is the object instance that I passed in UserData.

A strange thing is that if I set a break point on the catch block and when
the break occurs I run:

mg = Image.FromStream(p.PictureData);

from the Immediate Window, the call is successful and mg will hold the
expected image. That tells me that the problem is not in the image data
itself.

Please keep in mind that this does only happen in Vista X64, not in Vista X86.

Thanks in advance for any help with this.

Dale
 
P

Peter Duniho

[...]
where p is the object instance that I passed in UserData.

A strange thing is that if I set a break point on the catch block and when
the break occurs I run:

mg = Image.FromStream(p.PictureData);

from the Immediate Window, the call is successful and mg will hold the
expected image. That tells me that the problem is not in the image data
itself.

Well, it tells you that the problem is not in the image data >>> at the
time you enter the statement in the Immediate Window <<<. It tells you
nothing about the stream prior to that point.

You haven't posted a concise-but-complete sample of code for us to look
at. But the behavior you're describing sounds a lot like a race
condition. It could be related to the reading of the file and creation
of the memory stream, or in how you set the value used in the
ProgressChanged event, or it might not be a bug in your code at all
(though bugs in one's own code are MUCH more likely than bugs in .NET,
the latter is not impossible). Without seeing a complete sample of
code, it's not possible to say.

Pete
 
G

Guest

While you may be correct that p.PictureData is not legitimate in the try and
is legitimate in the catch, I don't see how that can happen. The
BackgroundWorker does not use the the instance of the object for p after
calling ReportProgress. I can't find any other alternate thread references
to the stream that would exist to indicate that a missing value would have
been updated in p in between.

In the BackgroundWorker code, ReportProgress would never be called if the
stream was not initialized.

Here is the code that initializes the stream:

First, I make sure the source image file exists:

if (File.Exists(picturePath))
{
imageStream = GetImageStream(picturePath);
}

Then I fill imageStream with the image by assigning the return value from
this code:

FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read,
FileShare.Read);
MemoryStream ms = new MemoryStream((int)fs.Length);

const int size = 4096;
byte[] bytes = new byte[4096];
int numBytes;
while ((numBytes = fs.Read(bytes, 0, size)) > 0)
ms.Write(bytes, 0, numBytes);

fs.Close();
fs.Dispose();

return ms;

Then I make sure that imageStream is not null and that it has something in
it with this code I just put in for troubleshooting. The if statement never
matches; the exception never gets thrown:

if (imageStream == null || imageStream.Length < 10000)
{
throw new Exception("Bad imageStream!!!");
}

And next comes a loop that uses the same stream several times including
calling ReportProgress where the exception occurs in the handler. In this
loop, some iterations will work and some will not. This pretty much proves
that the stream is valid since iteration 1 may work, 2 may not, maybe 3
through 6 will work, 7 will not, etc.


for (int count = 0; count < files.Length; count++)
{
ProcessImage(imageStream);
imagesProcessedCount++;

backgroundWorker1.ReportProgress(CalculatePercentComplete(fileCount,
imagesProcessedCount), new PictureProgress(
startingFolder,
imageFileName,
files[count],
fileCount,
imagesProcessedCount,
imageStream));
}



Because of the size and complexity of the application, recreating this bug
in code that could be posted here would be virtually impossible.

I guess I am hoping someone would have run across a similar roblem with GDI+
or System.Drawing in Vista X64, or with BackgroundWorker in Vista X64.

I don't know if it has any bearing or not, but if it is a race condition,
perhaps the fact that I have Vista X64 running on a dual quad-core Xeon
system and all the machines I run it on are single-core machines. I have had
quite a few people download the application from my site and while they have
had other feedback, this issue has never been reported by users either. I
doubt there has been any X64 installations; it isn't that widely spread.


Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA


Peter Duniho said:
[...]
where p is the object instance that I passed in UserData.

A strange thing is that if I set a break point on the catch block and when
the break occurs I run:

mg = Image.FromStream(p.PictureData);

from the Immediate Window, the call is successful and mg will hold the
expected image. That tells me that the problem is not in the image data
itself.

Well, it tells you that the problem is not in the image data >>> at the
time you enter the statement in the Immediate Window <<<. It tells you
nothing about the stream prior to that point.

You haven't posted a concise-but-complete sample of code for us to look
at. But the behavior you're describing sounds a lot like a race
condition. It could be related to the reading of the file and creation
of the memory stream, or in how you set the value used in the
ProgressChanged event, or it might not be a bug in your code at all
(though bugs in one's own code are MUCH more likely than bugs in .NET,
the latter is not impossible). Without seeing a complete sample of
code, it's not possible to say.

Pete
 
P

Peter Duniho

[...]
Because of the size and complexity of the application, recreating this bug
in code that could be posted here would be virtually impossible.

Then you are not likely to find the answer here, sorry to say.
I guess I am hoping someone would have run across a similar roblem with GDI+
or System.Drawing in Vista X64, or with BackgroundWorker in Vista X64.

While I appreciate the temptation of simply describing a problem and
hoping that someone recognizes it, that almost never works. I hope I'm
mistaken and someone does reply with the answer. But until you post a
concise-but-complete example of code that reliably reproduces the
problem, it's not likely someone can answer the question. There's too
much missing in the code that you did post.
I don't know if it has any bearing or not, but if it is a race condition,
perhaps the fact that I have Vista X64 running on a dual quad-core Xeon
system and all the machines I run it on are single-core machines.

Well, you could try to find someone willing to test it on a
multi-processor machine. It's true that race conditions often don't
manifest themselves until you run them on multi-processor computers.

Pete
 
J

Jeffrey Tan[MSFT]

Hi Dale,

Then, is it possible for you to create a little sample project to
demonstrate this problem? This will help us to analyze the problem. Since
your problem is a bit specific, I would not expect other people have
encountered the same problem.

Can you provide a complete stack trace of the exception? Since you may get
two different exceptions, I agree with Pete that this may be caused by some
race condition or threading issue. Also, do you use any unmanaged code in
your application?

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Thanks for your response, Peter.

You are probably right about the odds of finding the answer here but I did
want to try. I have certainly seen hundreds if not thousands of issues get
answered without complete executable code being posted including many that I
have answered and that I have had answered.

But considering the difficulty of describing this and the complexity of
posting it, I will probably have to burn a support incident. Oh well, I
guess I have to use them for something. :)

Thanks again for your help,

Dale
 
G

Guest

I just don't think I could hope to reproduce such an intermittent condition
with a scaled down application that can be posted here. Offline from here, I
can provide the complete application code.

There is no unmanaged code or references to any non-.Net libraries.

Because I am using the BackgroundWorker to manage threading and it is in the
normal events of the BackgroundWorker where the errors are occuring, I would
expect this to work unless there was a bug in the framework. There is only
one BackgroundWorker in the app.

I would not be disappointed or surprised if this issue ends up having to go
to product support for help. Just let me know what you think.

Regards,

Dale Preston
 
G

Guest

By the way, Peter, just in case you or anyone else wants to run the app on
Vista X64 or a multi-processor/core machine, the application can be
downloaded from
http://www.dalepreston.com/Blog/2007/03/id3-embed-pictures.html. You can
verify the safety of the app to some degree by reading
http://www.siteadvisor.com/sites/dalepreston.com.

And it runs fine for me on 32-bit Vista on a Core 2 Duo machine but that's
only 2 cores. The problem is only occuring on an 8-core machine. Those may
be hard to find for testing :)

Thanks,

Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA


Peter Duniho said:
[...]
Because of the size and complexity of the application, recreating this bug
in code that could be posted here would be virtually impossible.

Then you are not likely to find the answer here, sorry to say.
I guess I am hoping someone would have run across a similar roblem with GDI+
or System.Drawing in Vista X64, or with BackgroundWorker in Vista X64.

While I appreciate the temptation of simply describing a problem and
hoping that someone recognizes it, that almost never works. I hope I'm
mistaken and someone does reply with the answer. But until you post a
concise-but-complete example of code that reliably reproduces the
problem, it's not likely someone can answer the question. There's too
much missing in the code that you did post.
I don't know if it has any bearing or not, but if it is a race condition,
perhaps the fact that I have Vista X64 running on a dual quad-core Xeon
system and all the machines I run it on are single-core machines.

Well, you could try to find someone willing to test it on a
multi-processor machine. It's true that race conditions often don't
manifest themselves until you run them on multi-processor computers.

Pete
 
G

Guest

I guess because I typoed and used two punctuation marks in the address above,
the link is not interpreted correctly. Either manually remove the trailing
period and space or try this link to download the application:

http://www.dalepreston.com/Blog/2007/03/id3-embed-pictures.html

Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA


Dale said:
By the way, Peter, just in case you or anyone else wants to run the app on
Vista X64 or a multi-processor/core machine, the application can be
downloaded from
http://www.dalepreston.com/Blog/2007/03/id3-embed-pictures.html. You can
verify the safety of the app to some degree by reading
http://www.siteadvisor.com/sites/dalepreston.com.

And it runs fine for me on 32-bit Vista on a Core 2 Duo machine but that's
only 2 cores. The problem is only occuring on an 8-core machine. Those may
be hard to find for testing :)

Thanks,

Dale
--
Dale Preston
MCAD C#
MCSE, MCDBA


Peter Duniho said:
[...]
Because of the size and complexity of the application, recreating this bug
in code that could be posted here would be virtually impossible.

Then you are not likely to find the answer here, sorry to say.
I guess I am hoping someone would have run across a similar roblem with GDI+
or System.Drawing in Vista X64, or with BackgroundWorker in Vista X64.

While I appreciate the temptation of simply describing a problem and
hoping that someone recognizes it, that almost never works. I hope I'm
mistaken and someone does reply with the answer. But until you post a
concise-but-complete example of code that reliably reproduces the
problem, it's not likely someone can answer the question. There's too
much missing in the code that you did post.
I don't know if it has any bearing or not, but if it is a race condition,
perhaps the fact that I have Vista X64 running on a dual quad-core Xeon
system and all the machines I run it on are single-core machines.

Well, you could try to find someone willing to test it on a
multi-processor machine. It's true that race conditions often don't
manifest themselves until you run them on multi-processor computers.

Pete
 
J

Jeffrey Tan[MSFT]

Hi Dale,

Thanks for your feedback.

The newsgroup support nature and support boundary confines that it is hard
to troubleshoot production application here.

Yes, due to the complexity of this issue, I would agree that contacting
Microsoft CSS phone support should be the most efficient way to resolve the
issue.

You can contact Microsoft Product Support at 1-(800)936-5800 or by choosing
one of the options listed at:
http://www.microsoft.com/services/microsoftservices/srv_support.mspx

If you need further help, please feel free to post, thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top