[.net] LETHAL Console.WriteLine

Started by
10 comments, last by NexusOne 17 years, 6 months ago
I have a block of code I'm trying to debug. It uses a BitmapData object and iterates through the colors for fast image updating. While debugging I put in a Console.WriteLine command. But when it runs with this line the computer completely freezes, so that the mouse moves but nothing else works (i.e. can't click anywhere, windows are don't even say "not responding", they are fully dead and mouse clicks do nothing anywhere on the monitor (other windows, taskbar, etc). When I turn off the computer (which I'm forced to) and turn it on again, it occasionally gives me a BSOD (this is XP Pro x64) upon restart but it disappears too fast for me to read it then says "startup failed" and gives me a list of other startup options. When run without the Console.WriteLine none of this occurs. How is a writeline killing my computer?? My pointers in the bitmap memory are correct!
Graphics make the game! 8-)
Advertisement
Log to something else, like a file, so you can try and use that data to fix your problem.

Watch perfmon (look at memory and cpu) ... I bet you are using up one or both during a loop (causing the crash.

Likely there is write deadlock occuring, so watch for deadlocks. Is there more than one thread trying to write at the same time??

Try putting a lock statement around your console.writeline statement.

Lock ("please work")
{
system.console.writeline("your info")
}

It's likely that your error screen will give you a cor dump into one of the core libraries that is referenced by mscorlib. You can turn on a feature in VS.Net to break into other assemblies even if you don't have the source code. I think it is break into the disassembler or something... Also keep in mind that VS.Net is a 32 bit app running on the emulation layer for the 64 bit OS. Emulation is almost never a happy thing, especially if crazy things like programming, debugging, and or games are concerned.

Could be your OS hardware combination (is this a new machine for you?) ... I had some major pains with XP 64 bit not too long ago, though I'm not sure why. Could have been the hardware, or the software ...but the hardware was brand new and I tried with several replacement components of brand new stuff, and then gave up and had a shop try to do it, and then gave up on waiting for them eventually.


At the place where I used to work (wink, wink), we used windows XP 64 bit a lot (more than anyone I would say). It crashed a lot. Not ready for prime time yet. I would venture to make a rather accurate guess that it is another OS with a different name that was stripped down.

Vista will be much better in this regard.

Good luck, and go ahead and post more information, if you this didn't help, and I'll try and narrow it down for you a little more.
There is only 1 thread running (other than unrelated window listeners and such). I'm running from the command prompt, and the code is compiled with /platform:86 so it's 32 bit and emulated for my OS (required to work with some 32-bit DLLs).

I'll try your suggestions first chance tomorrow. For now here's my code. Some variables renamed here and whatnot for readability, so there may be typos. The method is supposed to draw one image (fore) on top of another (presumably larger) image (back) with the top-left of fore positioned at x,y on back.


	public void drawImage(Bitmap fore, Bitmap back, int x, int y){		if(fore == null || back == null) return;		int foreWidth = fore.Width, foreHeight = fore.height;		int realMinX = max(0, x), realMinY = max(0, y), realMaxX = min(x + subWidth, width), realMaxY = min(y + subHeight, height);		if(realMinX >= back.width || realMinY >= back.height || realMaxX <= 0 || realMaxY <= 0) return;		uint currentAlpha, currentRed, currentGreen, currentBlue, newAlpha, newRed, newGreen, newBlue;		unsafe{			BitmapData backData = back.LockBits(new Rectangle(realMinX, realMinY, realMaxX - realMinX, realMaxY - realMinY),				ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);			BitmapData foreData = fore.LockBits(new Rectangle(0, 0, subWidth, subHeight), ImageLockMode.ReadOnly,				PixelFormat.Format32bppArgb);			byte* backScan = (byte*)(backData.Scan0), foreScan = (byte*)(foreData.Scan0);			int backStride = backData.Stride, foreStride = foreData.Stride;			int backDataWidth = backData.Width, backDataHeight = backData.Height, foreDataWidth = foreData.Width,				foreDataHeight = foreData.Height;			uint* pointer1, pointer2;			float scale;			for(int i = 0; i < backDataHeight; i++, backScan += backStride - backDataWidth * 4,					foreScan += foreStride - foreDataWidth * 4){				for(int j = 0; j < backDataWidth; j++, backScan += 4, foreScan += 4){					pointer1 = (uint*)(foreScan);					pointer2 = (uint*)(backScan);					newAlpha = *foreScan;					Console.WriteLine(newAlpha);			//kills computer					/*if(newAlpha == 255) *pointer2 = *pointer1;					else if(newAlpha == 0);					else{						newRed = *(foreScan + 1);						newGreen = *(foreScan + 2);						newBlue =  *(foreScan + 3);						currentAlpha = *backScan;						currentRed = *(backScan + 1);						currentGreen = *(backScan + 2);						currentBlue = *(backScan + 3);						scale = newAlpha / 255f;						*(backScan + 1) = (byte)(currentRed + (newRed - currentRed) * scale);						*(backScan + 2) = (byte)(currentGreen + (newGreen - currentGreen) * scale);						*(backScan + 3) = (byte)(currentBlue + (newBlue - currentBlue) * scale);					}*/				}			}			fore.UnlockBits(foreData);			back.UnlockBits(backData);		}	}


[Edited by - NexusOne on October 16, 2006 12:01:08 PM]
Graphics make the game! 8-)
Quote:Original post by NexusOne
...

If only it were possible to get the forum to format your code for you...

CM
Quote:
If only it were possible to get the forum to format your code for you...

CM



Thanks
Graphics make the game! 8-)
why are you using uint for everything? It seems you should be using byte instead. Where is scanTemp defined?
Doesn't console writeline flush itself after the call ? and you're doing it for every pixel, that's a lot text flushing which isn't that quick anyway, you only need to see how slow the debug prints are when you're using directx and that churns out debug text..
Quote:
why are you using uint for everything? It seems you should be using byte instead. Where is scanTemp defined?


Some of the uints should probably be changed to bytes. I was still writing and re-writing this code. Sorry for the typos, if you scroll up I've corrected them now (unless there are more).

Quote:
Doesn't console writeline flush itself after the call ? and you're doing it for every pixel, that's a lot text flushing which isn't that quick anyway, you only need to see how slow the debug prints are when you're using directx and that churns out debug text..

This is run from the command line. Console.WriteLine on the command prompt is much faster than the debug prompt in VS. But the Console.WriteLine was only for debugging, it's not staying there. I just need to know how it crashes my computer, or things like this could happen in the future.

On a separate question, if one of you runs this code and uncomments the commented out part (it's necessary for it to work), does this method work for you guys? For me the colors end up badly distorted (trying saving the image to view it). If you run it, remember that both images have to already be in PixelFormat.Format32bppArgb. Obviously you can take out the Console.WriteLine if you run it on your computer. But I wonder if yours would crash or if it's just bc I'm on x64. Things seem to go wrong all the time on this OS. That's why I'm wondering if the colors will be correct for someone else who runs this even though they become incorrect over here.
Graphics make the game! 8-)
well, I don't know about the crashing.
Your image distortion might be caused by this:
*(backScan + 1) = (byte)(currentRed + (newRed - currentRed) * scale);*(backScan + 2) = (byte)(currentGreen + (newGreen - currentGreen) * scale);*(backScan + 3) = (byte)(currentBlue + (newBlue - currentBlue) * scale);


Suppose the current pixel in the back buffer was white.. then currentRed = 255, and then you add something to it and end up with something larger than 255, which you then cast to a byte and lose the most significant bits there. If you're trying to do transparency blending, which it looks like you are, then you should multiply currentRed by (1-scale).

Are you hoping to write this to be faster than just using System.Drawing.Graphics to draw to the bitmap?
Quote:
Suppose the current pixel in the back buffer was white.. then currentRed = 255, and then you add something to it and end up with something larger than 255, which you then cast to a byte and lose the most significant bits there. If you're trying to do transparency blending, which it looks like you are, then you should multiply currentRed by (1-scale).

Are you hoping to write this to be faster than just using System.Drawing.Graphics to draw to the bitmap?


I'm not adding newRed onto currentRed. If you look closely, the line you are referring to scales along the line between currentRed and newRed and sets currentRed to a value along that line designated by the newAlpha (remember, "newRed - currentRed" can be negative).

Normally I would not bother with pointers in C# at all, in fact I have a beautiful personalized Image class that uses Graphics to do high-level rendering, but it is unfortunately too slow on large image processing for my current purpose, which is a 2D game on my native resolution of 1280 x 1024 in 32-bit color.
Graphics make the game! 8-)

This topic is closed to new replies.

Advertisement