I have seen a few different answers on SO that discourage the use of Debug.Print while debugging applications .. but nobody ever goes into exactly why its bad. I googled it, of course, but the results didn't turn up anything usable.
Can anyone clarify why Debug.Print is so bad?
It's noisy - all the debug statements end up mixed together.
It's easily missed - there's a ton of other output in that stream as well, easy to miss stuff.
It doesn't give enough context - there's no stack trace, no current variable values if you forget to include them, etc...
It only goes one place (the debug output) so it's hard to send to a disk file, database, etc.
Basically, it's no good for logging since you can't control where it goes, and it's no good for debugging because the debugger does everything better.
There's really nothing wrong with it, there are just better options.
If you're going to be outputting data you may as well log it. If you do that you actually get something back from the investment.
Additionally printing out variable info is less effective than setting a break point and inspecting those values in the debugger. Particularly in VS where these tools are excellent.
Related
a coworker, who doesnt work here anymore, disabled the code-optimization of one of our projects some time ago. There is no way I can contact him anymore and looking at the changes he made with his commit I cannot see any reason as to why he did that.
Our program has some great bottlenecks and even though I am not sure if enabling this option again would bring any boost in performance, I would say its the better way to go..
The main problem here is that we would have to check every bit of this badly-written software for any side-effects which could take literal months to do..
My question here is if there are any reasons known as to why someone should deactivate this option and for what reason?
When debugging with that option turned on, some variables can't be inspected as their lifetime has been minimized. It is very likely he deactivated it to be able to debug more comfortably. There should be no effect on runtime apart from a slight slow down.
You can always try to check on a non-production environment if reactivating it helps with the bottlenecks you mention. That being said, do not expect any major speed-up.
I am developing a Windows Store application. Currently, I am getting intermittent hangs as described in this blog post. The issue appears to be that not enough space is given to remainder-defined column widths and TextBlocks attempting to format themselves (possibly due to the ellipsis processing). My app tends to hang indefinitely when this happens.
The question I have less related to how to solve the issue (as it seems to be described fairly well in the blog post), but instead how to find the issues. I have one fairly regularly (approximately one in five or ten start-ups) on a Hub Page, so I've been looking through there (as it's the most notable instance of issue), but it's a true Heisenbug in that it never seems to happen when debugging (or when you look for it).
So, how do I find the offending code? Is there just a pattern I need to look for (ColumnWidth="*"?). Is there a simpler way to solve this, such as changing the base style to remove one of the possibly offending properties listed in the blog post?
It seems possible that this is being caused by another issue, but this seems to be the most likely/plausible as of right now (as with the hubs I have a similar situation to what is being described there).
Also, is there a way to track when this happens in the wild? MSFT provides crash dumps on hangs, but they seem to give little to no information in them at all (and on top of that they only appear 5 days after they happen, which is less than ideal).
Thanks!
This is a complicated question to answer.
First, I think you have identified a real problem with WinRT. You theorize that the layout subsystem seems busy calculating your layout, and based on some condition that occurs around 20% of the time it does not finish in any reasonable time. Reasonable guess.
The problem, then, is when such an event does not occur during debug. In my personal development experience, errors that do not occur in debug are 99.99% timing related. Something is not finishing before a second process begins. Debugging lets those first, long process finish.
This is a real computer science question, and not so much a WinRT or Windows 8 question. To that end, the best answer I can give you without any code samples (why no code samples?) is the typical approach I employ when I reach the same dilemma. I hope it helps, at least a little.
Start with your brain.
I have always joked with developers just how much debugging can be done outside the debugger - and in your mind. Mentally walking the pipeline of your app and looking for race-condition dependencies that might cause deadlocks. Believe it or not, this solves a lot of problems a debugger could never catch - because debuggers unwind timing dependencies.
Next is simplicity.
The more complex the problem the less likely you will find the culprit. In the case of a XAML application, I tend to remove or disable value converters first. Then, I look to remove data templates. If you have element bindings, those go next. If simplifying the XAML does help - that's just the beginning to figuring it out. If it doesn't, things just got easier.
Your code behind can be disabled with just a few keystrokes and found guilty or innocent. It's the most likely place for your problem, I find, and the reason we work so hard to keep it simple, clean, and minimal. After that, there's the view model. Though it's not impossible for your view model to be the one, and indeed you still have to check, it's probably not the root of your evil.
Lastly, there's the app pipeline that loads your page, loads your data, or does anything else. Step by step your only real option is to slowly remove things from your app until you don't see the problem. Removing the problem, though is not solving it. That's a case by case thing based on your app and the logic in it. Reality is, you might see the problem leave when removing XAML, while the real problem is in the view model or elsewhere.
What am I really saying? The silver bullet you are asking for really isn't there. There are several Microsoft tools and even more third party tools to look for bottlenecks, latency problems, slow code, and stuff - but in all reality, the scenario you describe is plain ole programming. I am not saying you aren't the victim of a bug. I'm saying, with the information we have, this is all I can do for you.
You'll get it.
Third thing to do is to add logging, and instrumentation to your app.
Best of luck.
Given that Jerry has answered this at a higher level I figured I would add in the lower level answers that from the way your question is phrased makes me think you are interested in. I guess first I would like to address the last item which is the dump files. There is a mechanism for getting dump files of a process 'in the wild' that Microsoft provides which is through Windows Error Reporting. If you are wanting to collect dump files from failed client processes you could sign up for Windows Error Reporting (I must admit I have never actually done it, but I did look into it and tried to get my current employer to allow me to do this, but it didn't end successfully). To sign up go to the Establish a Hardware/Desktop Account Page.
As far as what to do with dump files once you get them, you would be wanting to download the debugging tools for windows (part of the Windows SDK download) and/or the Debug Diag Tool (I must confess I am more of a debugging tools for windows user than a Debug Diag user). These will provide you with the tools to look into what is going on at a lower level. Obviously you can only go so far as you won't have access to private Microsoft symbols, but you do have access to public symbols and usually those are enough to give you a pretty good idea of the problem area.
Your primary tools will depend on how reproducible the issue is. If it is only reproducible on some client machines then you will have to rely on looking at a single dump file that you probably got a hold of from Windows Error Reporting. In this case what I would do is open it up using the appropriate version of Windbg (either x86 or x64) and look at what was going on at the time the dump was taken. Depending on how savvy you are depends on how far you can go. Probably a simple starter would be to run
.symfix
.reload
.loadby sos clr
!EEStack
This will load Microsoft public symbols, the sos extension dll for dealing with Managed code inspection, and then will dump the contents of the stack for each thread in the process. From looking at the names of the method that appear on the call stacks you might be able to get a pretty good idea of at least the area of the code where the lock is occuring.
You can go much farther than this as Windbg provides the ability to go pretty deep into deadlock analysis (for instance there is an extension available for Windbg called sosex that provides a command !dlk which can sometimes automate the detection of a deadlock for you from a single dump file. To load an extension dll into Windbg you just have to download it and then call .load fullpathtodll). If the problem is reproducible locally you might even be more successful with WPA/WPR or if you are really fortunate a simple procmon trace. These tools do have a pretty decent barrier to entry as they take some time to learn. But if you are really interested in the topic your best resources would be the Defrag Tools series on Channel9 and anything by Mario Hewardt (especially his book "Advanced .Net Debugging"). Again, getting familiar with these tools can take a bunch of time, but at the very least if you just know how to dump the contents of the stacks from a dump file you can sometimes get what you need just from that so a basic understanding of these tools can be beneficial as well.
This might not be possible but it would be hugely helpful with debugging. Sometimes random bugs occur when the program is running. I'd like to be able to type something in (a string) and then it would grab a variable with the name of that string and return its value.
int mainNumber = 89;
Input: retrieve mainNumber
Output: 89
Is something like that possible? I don't want to have to create debugs for every single variable I have on the off chance something could go wrong. I know I could wait for the bug to occur, stop the program, throw a debug in and wait again, but this would be faster.
You need to learn about the variable, watch and immediate windows of Visual Studio.
Would the 'immediate window' be what you're looking for? http://msdn.microsoft.com/en-us/library/f177hahy(v=VS.100).aspx
I would suggest reading up on Trace and Debug in .NET. You can typically switch Trace and Debug statements off and on from a program's config file, thus not affecting your runtime performance unless you want these dumps. Then you can sprinkle Trace.Write(...) and Debug.Write(...) statements in your code to provide the output you desire.
Based on your comment, it sounds like you're going to need to do some research. Here are some things to consider/try:
What is the bug? Is an exception being thrown, is data not coming back correctly, etc. Identify what it is that you're trying to root cause.
Do you know under what circumstances the bug happens? Since you said random, chances are you don't yet know the answer to that.
Are you able to reproduce or see the bug in a test environment?
One option that I've done in the past is to add logging (usually to a text file) to the application in question. I put in logging in the areas of interest, and timestamp the entries. Grab enough information so you can adequately identify the actions that are occurring (before/after states of variables/objects, any supporting information that identifies the action, etc).
When a bug is reported (or reproduced), if the reporter gives enough information (i.e., time, what they were doing, other things particular to the app or what they were doing) you can look in your log files and see what was going on.
Once you have that information, you can either identify the root cause, or narrow it down to a more specific area and focus your efforts there.
It can be something of an iterative process, depending on how big the app is and how large the area of possible problems can be.
I'm writing a plug-in for another program in C#.NET, and am having performance issues where commands take a lot longer then I would. The plug-in reacts to events in the host program, and also depends on utility methods of the the host program SDK. My plug-in has a lot of recursive functions because I'm doing a lot of reading and writing to a tree structure. Plus I have a lot of event subscriptions between my plugin and the host application, as well as event subscriptions between classes in my plug-in.
How can I figure out what is taking so long for a task to complete? I can't use regular breakpoint style debugging, because it's not that it doesn't work it's just that it's too slow. I have setup a static "LogWriter" class that I can reference from all my classes that will allow me to write out timestamped lines to a log file from my code. Is there another way? Does visual studio keep some kind of timestamped log that I could use instead? Is there someway to view the call stack after the application has closed?
You need to use profiler. Here link to good one: ANTS Performance Profiler.
Update: You can also write messages in control points using Debug.Write. Then you need to load DebugView application that displays all your debug string with precise time stamp. It is freeware and very good for quick debugging and profiling.
My Profiler List includes ANTS, dotTrace, and AQtime.
However, looking more closely at your question, it seems to me that you should do some unit testing at the same time you're doing profiling. Maybe start by doing a quick overall performance scan, just to see which areas need most attention. Then start writing some unit tests for those areas. You can then run the profiler while running those unit tests, so that you'll get consistent results.
In my experience, the best method is also the simplest. Get it running, and while it is being slow, hit the "pause" button in the IDE. Then make a record of the call stack. Repeat this several times. (Here's a more detailed example and explanation.)
What you are looking for is any statement that appears on more than one stack sample that isn't strictly necessary. The more samples it appears on, the more time it takes. The way to tell if the statement is necessary is to look up the stack, because that tells you why it is being done.
Anything that causes a significant amount of time to be consumed will be revealed by this method, and recursion does not bother it.
People seem to tackle problems like this in one of two ways:
Try to get good measurements before doing anything.
Just find something big that you can get rid of, rip it out, and repeat.
I prefer the latter, because it's fast, and because you don't have to know precisely how big a tumor is to know it's big enough to remove. What you do need to know is exactly where it is, and that's what this method tells you.
Sounds like you want a code 'profiler'. http://en.wikipedia.org/wiki/Code_profiler#Use_of_profilers
I'm unfamiliar with which profilers are the best for C#, but I came across this link after a quick google which has a list of free open-source offerings. I'm sure someone else will know which ones are worth considering :)
http://csharp-source.net/open-source/profilers
Despite the title of this topic I must argue that the "best" way is subjective, we can only suggest possible solutions.
I have had experience using Redgate ANTS Performance Profiler which will show you where the bottlenecks are in your application. It's definitely worth checking out.
Visual Studio Team System has a profiler baked in, its far from perfect, but for simple applications you can kind of get it to work.
Recently I have had the most success with EQATECs free profiler, or rolling my own tiny profiling class where needed.
Also, there have been quite a few questions about profilers in that past see: http://www.google.com.au/search?hl=en&q=site:stackoverflow.com+.net+profiler&btnG=Google+Search&meta=&aq=f&oq=
Don't ever forget Rico Mariani's advice on how to carry out a good perf investigation.
You can also use performance counter for asp.net applications.
I just ran into one of the most mind boggling errors ever. false == true What information would you guys need to confirm/debug this behavior? I've never seen anything like it.
VS2008 sp1
Debug Mode | Any Cpu
IIS 7.5
Edit:
I did a clean->rebuild and still the same.
Here's the assembly and registers. I don't know how to read this, but maybe it could help someone else.
I suppose your PDB files are not in phase and you have differences in what's really executed and what Visual Studio sees as a line number. Try rebuilding. We all know that it is impossible to have true = false, or the world as we know it may change :-)
Does it actually throw the error? The debugger can often highlight the wrong lines if you feed it the wrong pdb, so this could be a false lead. It is also trivial to reproduce using the "immediate" pane to change the value after the test.
If result was a field or a captured variable, it could also be set by external code (perhaps on another thread).
If result wasn't a bool but your own custom type, you could just override ==, or provide a custom true/false operator.
Probably the source does not correspond to the running version or there's a bug in the debugger.
Part of the problem is that you're assuming the debugger is 100% correct. It in fact is not and is subject to a number of situations where values can have incorrect or misleading displays. The most common causes of this are ...
Mismatched PDB files. This will usually lead to at least a warning dialog in the debugger about mismatched source files but not always
Simple data inspection or display error by the underlying expression evaluator. Not likely in this case as it's a simple local and a primitive type.
Optimizations causing the data to be displayed incorrectly.
But it in fact is almost certainly not false. The easiest way to verify this is to use a Debug.WriteLine call to print the value out to the output window.
Are you sure that's the exception being thrown? My hunch is that your method isContextSignatureValid is actually throwing an exception, but the Visual Studio debugger can get ahead of itself sometimes and highlight a line that is not actually throwing the exception.
Maybe you moved the current instruction pointer (yellow arrow) with your mouse inadvertently while in break mode... It happened to me once and I flipped out. :-)
Just to add a little suggestion:
If you ever get confusing results from the debugger, stick a Console.WriteLine() in there and get the code itself to tell you what is going on. This can often clear up confusion.
(You can also get an effect like this when debugging release code, but you said it was a debug build which eliminates that suspect)
I've seen this sort of thing before. A co-worker was convinced he'd uncovered a bug in the .Net Framework or CLR. In the end it was just an old assembly or pdb synch problem.