For a demonstrating, take a look at the following section of this video.
Basically, I know this is possible in Visual Studio Community Edition 2015. I was wondering:
a) Is this related to Intellitrace and "Historic debugging"?
b) Will there be any side-effect when I do this? Or is this just moving the instructions backwards and that's it?
It is just moving the instruction pointer backwards and that's it, to use your own words.
This means that:
Any side-effects already incurred between where you drag it to and where you dragged it from has already incurred and won't be reversed.
Any variables changed in the same section of instructions will still be changed, they are not reversed to whatever values they had at the point you you drag the instruction pointer to
So you can use this debugging aid to either force the program to take a path it didn't (for instance by dragging the instruction pointer inside an if-statement it skipped), to skip (by dragging the instruction pointer past some code you don't want to execute), or to rerun some code.
But you must be aware of the above limitations. If the code is not safe to be executed again, then doing so will likely not help you debug.
It's been doable for a long while now. Everything that happened to the point from where you are dragging the cursor already happened, so you will essentially be re-doing that bit.
There are no REAL consequences, unless you are processing something or saving to database etc., as writing the same existing data might throw an exception or mess with processing of some data.
All of the variables that have been set (even if you drag the cursor higher than they initialize) will retain the value they had from the spot you've dragged the cursor upward.
Related
I just made a silly mistake and I ended up with an infinite loop inside my Update(). After that I wasn´t able to stop the Play Mode. Actually I wasn´t able to do anything else with Unity until I restarted it.
My question is, does anyone know how to stop the Play Mode in Unity gracefully? Is there any shortcut or some lines of code to force a timeout?
Extra Note: I have been looking for a solution to this issue for a while, unfortunately without success. However I found a solution to a side-effect of this problem. When you press ctrl-alt-del you can loose everything you haven´t save in your scene (which can be hours of work).
So Unity does an auto-save when you hit play, and the scene backup is in the Temp folder, as long as you haven´t run Unity again after a force-quit.
The following worked for me (Props to #LinusR and by extension #Kinxil) This is just a quick step-by-step.
This should work for you if you are using Visual Studio w/ Unity Tools.
Find the loop:
Open Visual Studio (if not already open)
Click Attach to Unity (if not already attached)
Click Break All (pause II symbol)
Open the Call Stack, Threads and Immediate windows. (All in Debug → Windows →)
Looking at the Call Stack, click through the threads in the Threads window.
Stop when you find the thread that the loop is on. (Call Stack helps with this)
You must be on the thread with the loop to execute necessary commands in the Immediate window.
Now get me out of here!:
[LinusR's solution seemed to be the most bullet-proof and versatile.]
Break the loop with a null value and some other options
In the Immediate window, set one of the nullable objects/fields/properties used in the loop to null e.g. for Thread.SpinWait.SpinUntil(() => someObject.NeverTrue());
someObject = null;
Unity will respond again in this instance (providing someObject remains null).
An alternative for SOME loops is simply breaking and changing the instruction or values and/or dragging the current instruction arrow (yellow arrow) out of the loop, though this may not be possible depending on the type of loop.
Think about how the loop works; How often is it executed? Will it be called each frame? etc.
Nothing working? Read the other answers here, Get creative with the Immediate window. Also in future it would be wise to have Error Pause enabled at all times in Unity.
I just got into this situation: accidental infinite loop, stuck in play mode on a scene with unsaved work, Unity unresponsive.
But I was lucky enough to have Monodevelop open, even though I was mainly using Sublime for scripting. I pressed the button to start debugging near the top left of the Monodevelop window, then hit the pause button. Execution paused on a line in the middle of my infinite loop. Windows task manager confirmed Unity was no longer locking the CPU.
In Monodevelop, I was then able to find an object obj that the next line would attempt a method call on, and use the "Immediate" window to execute obj = null. Then unpause. Unity itself now unlocks because of the null pointer error, and I could take it out of play mode and save my work.
(Unity 2017.4.1f1 Personal, Windows 10 Home x64, Monodevelop 5.9.6)
Note, I got the idea from reading #Kinxil's answer, but I had to take a slightly different approach because there was no "blocking value". I had a for (;;) loop that had previously been inside a coroutine and I changed it to be inside a FixedUpdate() without removing the loop. :\ So causing an exception was the only option I could think of.
Solution
Attach your IDE to Unity
Pause execution
Exit the loop
Optionally execute Debug.Break() to prevent the loop to enter again at the next Update()
Resume execution
Return to the Unity editor
For Visual Studio
(I haven't tested the other IDE's)
Click Attach to Unity
Wait for the process to attach (sometimes take a while)
Click Break All (pause II symbol)
Click on menu Debug → Windows → Threads
Click on the thread that contains your source code (see location column)
In your source code (text editor), move the program pointer (yellow arrow) outside the loop by dragging it to a different line in your source code.
Optionally in the case where the loop is inside some Update() event that would re-enter the loop again:
Click on menu Debug → Windows → Immediate
Type UnityEngine.Debug.Break() inside the Immediate Window and press Enter
Finally resume execution (Play button) and return to Unity editor.
Unity should now be in a "Paused" state where you can inspect what went wrong or "Stop" the Play Mode.
For me, this worked.
How To Get out of A infinite loop
Open Visual Studio.
Click "Attach to Unity" at the top (if not already clicked)
Add a breakpoint to the infinite loop by clicking the area to the left of the line number where the loop is.
You will see a yellow arrow where the breakpoint is. Click and drag this arrow to a spot outside the loop (preferably after)
Remove your current breakpoint.
Go back to unity and it will most likely take a second to unfreeze but after it unfreezes, you should be able to click the play button to stop play mode.
Boom! Panic attack averted.
It's a shame, Unreal Engine is for the most part really good at detecting infinite loops and exiting when they do, but Unity almost never seems to. It's tough to find out what's going on because Debug.Log doesn't fire until the frame completes so you can't see what's going on. A workaround to just try and see what's going on is to use some sort of limiter like this:
int limiter = 0, loopCap = 10000;
while (SomeCondition && limiter < loopCap)
{
// Do something
limiter++
}
if (limiter >= loopCap) Debug.Log("Infinite Loop avoided");
Of course, that's a much easier example because while loops can very easily become infinite loops, but if you have a ball park for where it could be happening, you could put a limiter there.
And this is only for debugging purposes so you're not having to cancel it via Task Manager. Ideally, you can find out what was the problem and remove the limiter.
I had an infinite loop a few days ago and I had no idea where it was going wrong, so I just commented out the code and then uncommented it out until it broke again, and was able to figure out where it came from.
Easily said (for MS Visual Studio):
Attach the debugger.
Add a breakpoint at a line that is called by the the infinite loop.
When the break point is reached, modify a variable to cause e.g. an null exception in consequence. You can do that in the "Locals" window (should be open when debugging; otherwise Debug/Windows/Locals or Alt+4).
Continue execution in the code editor.
Result: The Unity IDE indicates the exception and you can hit the stop-button.
Nothing else was needed in my case. Alternatively, in step 3 you might be able to change a local variable to a value that just ends the loop without an exception. But that will be only then useful, if that inifinite loop code is not called directly again afterwards.
Visual studio (I'm using Community 2015) allows you to drag and drop the yellow execution pointer around in the same function.
Is there a way to move that pointer up the stack, and especially when the debugger is waiting on the user after an exception has been thrown?
EDIT: Ideally no user code should execute during that process, as it can mess things up with other variables
I found a way. This is maybe not the easiest way around, but it's always possible to
first drag and drop the yellow arrow to the end of the current function
the execute as many step-out (Shift-F11) and "drag-to-end-of-function" as required
Of course it will "execute" some code, but if carefully done, it's only stack managing code, not user code, thus should not interfere with user variables.
Use the 'Step Out' functionality.
Shift + F11
is the shortcut by default.
Just a caveat: stepping out will execute the rest of the code in the method before going back up the stack.
Suddenly when I am debugging, say I remove a break point I no longer need then hit play or restart my program, and suddenly the same break point is back.
I clear it again save, and it is back again.
In some cases I remove a break point in others I add a break point.
It seems at random it either brings back or removes the break point or moves the existing break point a line or 2 to the wrong spot.
I have tried restarting VS a few times which works at first but for only a short time.
I have never seen this before and it scares me VS could be behaving so badly.
Is there any easy solution such as clean break points (I would rather not remove all of them)?
In my experience, the behavior you describe is a sign that the .suo-file (solution-wide user options - located in the solution folder) is corrupt. To test this, you can rename or move the file to an other folder. After that, all your breakpoints and many other settings (e.g. which code-files were opened) will be gone, but the breakpoints should behave as usual again.
Edit:
If you don't want to lose your breakpoints, you can export and import them from the breakpoints-window. I think this is a new feature of VS2012 (I tried it in the Premium Edition).
An other possibility is that you are encountering a "feature" that is described here:
http://connect.microsoft.com/VisualStudio/feedback/details/391642/permanently-remove-a-breakpoint-in-visual-studio-during-debugging
Visual Studio opens source code on top of the stack when I "break all" while debugging; I want to keep the cursor on the document I'm currently working on, without any other document or window (e.g.: no symbols loaded) being opened.
There is a way to stay on the current document, but that requires creating a Visual Studio add-in and a new UI command in the Debug toolbar. Credits for this answer should actually also go to openshac, who posted a similar SO question and also gave a workaround in his OP by using a macro.
The implementation is fairly simple (it took me a few minutes to have it working). First, in the add-in project, modify the Exec method in the Connect.cs file like this:
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if(commandName == "BreakInCurrentDocument.Connect.BreakInCurrentDocument")
{
// here's where the magic happens
// ******************************
var activeWindow = _applicationObject.ActiveWindow;
_applicationObject.Debugger.Break();
if (_applicationObject.ActiveWindow != activeWindow)
{
_applicationObject.ActiveWindow.Close(vsSaveChanges.vsSaveChangesNo);
}
// ******************************
handled = true;
return;
}
}
}
After creating and registering the add-in, just:
click TOOLS on the Visual Studio's menu
Customize
Commands
Choose the "Toolbar" radio button
Select "Debug"
Add Command...
From the "Addins" category, choose your custom add-in.
That's it.
Latest build of VSCommands extension (free version) available from http://visualstudiogallery.msdn.microsoft.com/a83505c6-77b3-44a6-b53b-73d77cba84c8 has just what you want.
It adds a Break In Current Document button to Debug Toolbar and Debug Menu:
http://vscommands.squaredinfinity.com/Media/VSCommands/BlogPost//blog/breakincurrentdocument.png
It's a feature.. when you do "break all" then it is assumed that your process has hung. The first thing you might be interested in such case is - WHERE. Hence, it's directing you right down to the 'current' place that is being executed. IIRC, this is defacto standard for all low-level debuggers. If you don't want the "no symbols loaded" just mark the 'show disasembly' and it will never pop up again:) (of course, instead, you will see the exact point of stop. And yes, this is also a feature that I myself used many times to debug unknown library code)
On the other hand, if you know where you want the code to stop, place the breakpoint there instead.
On yet another hand (as if we had three), if you want to actually stop the application - stop it, don't break, just stop.
I sense that your actual problem lies in the fact that you use one of the features in a wrong way, and therefore another feature bugs you. Please tell me, what do you use the "break all" for and how/why does it collide with your current text-editing. Why can't you stop or break-at-here instead? Or "detach"?
Anyways, I have to admit that as a feature, there should be some option for turning it off, just for the sake of configurability of the IDE.
EDIT
AAhh.. you're right. I've completely forgot about the glorious edit&continue. I'm not joking/teasing, E&C is a great feature that I wish all other platforms had. I've forgot about it, because... I extensively use lambdas, generics, foreachs and etc features that effectively block edit-and-continue.
Anyways, the point is, since that the edit-and-continue is the golden feature that you'd like to use - the application must be in 'break' mode. However, nevertheless how do 'break'/'pause' etc it, the IDE will assume it that the PAUSE was you goal, not editing, hence it will show you where did you pause the app.
There are a few options in MSVS like "show just my code" that may help you a little, but it will not solve the problem: edit-and-continue during debugging was designed for "small, local edits". Like, if(x>0)throw new uncaught() instead if(x<0)throw new uncaught(). Your app stopped on assertion or breakpoint and is about to crash, first-change exception handler fired off and here's your chance! You unwind the crash handler, correct the code, then run. Everything in the same one method which you had the stop occur in, as a way of just-in-time patches..
This is one of the main problems why can't you add methods, classes, modify generics, etc during E&C session: ie. editing your current lambda or current foreach might be OK, but the IDE would be not able to relocate the flows and execute the new code properly. This is a bit similar to why you sometimes see the "stale code" warning, but with those code constructs it is even harder to analyze, and therefore not implemented. And probably will never hit the top of MS's TO-DO list :/
The current boom in .Net/C# is not 'live development' but 'notaliveyet development' heavily supported by modularity and unit testing, where you put the effort to be able to test most of the features of the application off-line.. But that's a paradigm shift and for small projects or for local desktop development sometimes it is simply an overkill.
I have some drag and drop functionality I am using in an xceed grid. When I try to drag and item down just one row, it doesn't work. But if I put a break point in my drop method and do the drop then, it has changed when I come back to the UI. What might cause it to behave differently whether I break into the code or not?
If you "pause" your application using a debugger breakpoint, the state of the system (e.g. mouse button state) can change while it's paused, and thus be different when you allow the program to continue running. This can cause a very different behaviour than if the program were running normally. As a result of this, debugging drag and drop problems using breakpoints is often impossible.
In these situations a good approach is often to go back to basics and use a Debug.WriteLine (or similar) to dump useful information about the state of your variables as it runs "normally" (instead of killing it with a breakpoint). Then you can examine this dumped information at your leisure after the program has finished the drag, in order to work out what was happening at each stage in the process and work out why it failed.