I'm trying to debug a really large c++/c program in Visual Studio. Changing value of one parameter changes the result dramatically. I want to record a call stacks for both runs and diff them.
Does anybody know how to dump a call stack to a file in VS without setting breakpoints and using Select ALL/Copy in the window?
Thanks.
You can use System.Diagnostics.StackTrace to get a string representation of the current call stack and write that to a file. For example:
private static writeStack(string file)
{
StackTrace trace = new StackTrace(true); // the "true" param here allows you to get the file name, etc.
using (StreamWriter writer = new StreamWriter(file))
{
for (int i = 0; i < trace.FrameCount; i++)
{
StackFrame frame = trace.GetFrame(i);
writer.WriteLine("{0}\t{1}\t{2}", frame.GetFileName(), frame.GetFileLineNumber(), frame.GetMethod());
}
}
}
Then, whenever you want to write the current stack, just call writeStack(somePath).
Take a look at this codeproject example which uses the StackWalk64 API.
Related
I want to be able to do something like this:
for(i = 0; i < 10; i++) {
//if any button in the array is pressed, disable it.
button[i].setOnAction( ae -> { button[i].setDisable(true) } );
}
However, I get a error saying "local variables referenced from a lambda expression must be final or effectively final". How might I still do something like the code above (if it is even possible)? If it can't be done, what should be done instead to get a similar result?
As the error message says, local variables referenced from a lambda expression must be final or effectively final ("effectively final" meaning the compiler can make it final for you).
Simple workaround:
for(i = 0; i < 10; i++) {
final int ii = i;
button[i].setOnAction( ae -> { button[ii].setDisable(true) } );
}
Since you are using lambdas, you can benefit also from other features of Java 8, like streams.
For instance, IntStream:
A sequence of primitive int-valued elements supporting sequential and parallel aggregate operations. This is the int primitive specialization of Stream.
can be used to replace the for loop:
IntStream.range(0,10).forEach(i->{...});
so now you have an index that can be used to your purpose:
IntStream.range(0,10)
.forEach(i->button[i].setOnAction(ea->button[i].setDisable(true)));
Also you can generate a stream from an array:
Stream.of(button).forEach(btn->{...});
In this case you won't have an index, so as #shmosel suggests, you can use the source of the event:
Stream.of(button)
.forEach(btn->btn.setOnAction(ea->((Button)ea.getSource()).setDisable(true)));
EDIT
As #James_D suggests, there's no need of downcasting here:
Stream.of(button)
.forEach(btn->btn.setOnAction(ea->btn.setDisable(true)));
In both cases, you can also benefit from parallel operations:
IntStream.range(0,10).parallel()
.forEach(i->button[i].setOnAction(ea->button[i].setDisable(true)));
Stream.of(button).parallel()
.forEach(btn->btn.setOnAction(ea->btn.setDisable(true)));
Use the Event to get the source Node.
for(int i = 0; i < button.length; i++)
{
button[i].setOnAction(event ->{
((Button)event.getSource()).setDisable(true);
});
}
Lambda expressions are effectively like an annonymous method which works on stream. In order to avoid any unsafe operations, Java has made that no external variables which can be modified, can be accessed in a lambda expression.
In order to work around it,
final int index=button[i];
And use index instead of i inside your lambda expression.
You say If the button is pressed, but in your example all the buttons in the list will be disabled. Try to associate a listener to each button rather than just disable it.
For the logic, do you mean something like that :
Arrays.asList(buttons).forEach(
button -> button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false);
}
}));
I Also like Sedrick's answer but you have to add an action listener inside the loop .
I have the following UnitTest:
[TestMethod]
public void NewGamesHaveDifferentSecretCodesTothePreviousGame()
{
var theGame = new BullsAndCows();
List<int> firstCode = new List<int>(theGame.SecretCode);
theGame.NewGame();
List<int> secondCode = new List<int>(theGame.SecretCode);
theGame.NewGame();
List<int> thirdCode = new List<int>(theGame.SecretCode);
CollectionAssert.AreNotEqual(firstCode, secondCode);
CollectionAssert.AreNotEqual(secondCode, thirdCode);
}
When I run it in Debug mode, my code passes the test, but when I run the test as normal (run mode) it does not pass. The exception thrown is:
CollectionAssert.AreNotEqual failed. (Both collection contain same elements).
Here is my code:
// constructor
public BullsAndCows()
{
Gueses = new List<Guess>();
SecretCode = generateRequiredSecretCode();
previousCodes = new Dictionary<int, List<int>>();
}
public void NewGame()
{
var theCode = generateRequiredSecretCode();
if (previousCodes.Count != 0)
{
if(!isPreviouslySeen(theCode))
{
SecretCode = theCode;
previousCodes.Add(previousCodes.Last().Key + 1, SecretCode);
}
}
else
{
SecretCode = theCode;
previousCodes.Add(0, theCode);
}
}
previousCodes is a property on the class, and its Data type is Dictionary key integer, value List of integers. SecretCode is also a property on the class, and its Data type is a List of integers
If I were to make a guess, I would say the reason is the NewGame() method is called again, whilst the first call hasn't really finished what it needs to do. As you can see, there are other methods being called from within the NewGame() method (e.g. generateRequiredSecretCode()).
When running in Debug mode, the slow pace of my pressing F10 gives sufficient time for processes to end.
But I am not really sure how to fix that, assuming I am right in my identification of the cause.
What happens to SecretCode when generateRequiredSecretCode generates a duplicate? It appears to be unhandled.
One possibility is that you are getting a duplicate, so SecretCode remain the same as its previous value. How does the generator work?
Also, you didn't show how the BullsAndCows constructor is initializing SecretCode? Is it calling NewGame?
I doubt the speed of keypresses has anything to do with it, since your test method calls the functions in turn without waiting for input. And unless generateReq... is spawning a thread, it will complete whatever it is doing before it returns.
--after update--
I see 2 bugs.
1) The very first SecretCode generated in the constructor is not added to the list of previousCodes. So the duplicate checking won't catch if the 2nd game has the same code.
2) after previousCodes is populated, you don't handle the case where you generate a duplicate. a duplicate is previouslySeen, so you don't add it to the previousCodes list, but you don't update SecretCode either, so it keeps the old value.
I'm not exactly sure why this is only showing up in release mode - but it could be a difference in the way debug mode handles the random number generator. See How to randomize in WPF. Release mode is faster, so it uses the same timestamp as seed, so it does in fact generate exactly the same sequence of digits.
If that's the case, you can fix it by making random a class property instead of creating a new one for each call to generator.
Hi people i am currently working at my second visual studio made project :) . I am a delphi coder so please excuse my ignorance.
I want to write a simple routine to list some files and i wanted to write a simple function like Delphi's
IncludeTrailingPathDelimiter()
It's a simple function witch adds a \ to a file path if is not there...
So i came up with this
void listfiles(wchar_t * root)
{
if (root[wcslen(root) - 1] != L'\\')
wcscat_s(root,wcslen(root)+2,L"\\");
printf("%S",root);
}
It works but after exiting the function i get an (Stack Corruption) over this line
wcscat_s(root,wcslen(root)+2,L"\\");
What am i doing wrong do i need to allocate memory to the new created buffer or what?
Using the safe string functions is fine, but you do need to use them properly. The 2nd argument to wcscat_s() is the size of the buffer. You don't know the size of the buffer in this code, it most certainly isn't wcslen(root)+2. Rewrite the function like this:
void listfiles(wchar_t * root, size_t rootSize)
{
if (root[wcslen(root) - 1] != L'\\')
wcscat_s(root, rootSize, L"\\");
printf("%S",root);
}
...
wchar_t buffer[666];
...
listfile(buffer, sizeof(buffer) / sizeof(buffer[0]));
And now the debugger will step in when your buffer is too small. It is.
I have some code, that build up a proxy from a type. It work perfekt.
Then I have add in the setter emit code, that it has to push a isDirty bit, when it is call. This fail, why?
If I run the code without the isDirty bit, it works.
If I run the code with the isDirty bit, it works in debug, but is start the disassembly window up in visual studio.
If I run the code with the isDirty (without-debug) the program crash (not responding) but when I hit cancel, it starts working and show all de rigth data.
PropertyBuilder property = proxy.DefineProperty(propertyInfo.Name, propertyInfo.Attributes, propertyInfo.PropertyType, null);
MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual;
MethodBuilder setMethod = proxy.DefineMethod("set_" + propertyInfo.Name, attributes, typeof(void), new Type[] { propertyInfo.PropertyType });
ILGenerator setIL = setMethod.GetILGenerator();
setIL.Emit(OpCodes.Ldarg_0); // load this on the stack - where this is the type we are creating
setIL.Emit(OpCodes.Ldarg_1); // load first parameter on the stack
setIL.Emit(OpCodes.Call, propertyInfo.GetSetMethod());
{
//error here: when this is uncomment, it fails
// // set the isDirty bit
// setIL.Emit(OpCodes.Ldarg_0); // load this on the stack
// setIL.Emit(OpCodes.Ldc_I4_1, 1); // push a number on the stack
// setIL.Emit(OpCodes.Stfld, isDirtyField); // save the value on the stack in field
}
setIL.Emit(OpCodes.Ret);
property.SetSetMethod(setMethod);
I have a hard time, seeing why this fails? Need some help from the experts :)
// dennis
I'm not sure if this is your only issue, but you are using the wrong Emit overload when emitting your Ldc_I4_1 opcode. You should do either:
setIL.Emit(OpCodes.Ldc_I4_1)
or
setIL.Emit(OpCodes.Ldc_I4, 1)
The first option will result in a slightly smaller IL method body since it uses a specialized opcode, whereas the second one is not specific to the number being loaded.
I've got a designer that relies on the existence of other solution items. If one of those items is deleted the designer crashes and you have to edit as XML to fix. Not exactly user friendly.
I do, however, have the DTE object representing the instance of Visual Studio, as well as the ProjectItems I am dependent on.
Is it possible to, somewhere in the depths of the DTE, register a listener for the deletion of that ProjectItem? And, if so, How would I do it?
It looks like the culprit here is garbage collection. I found the following two event sets behaved identically.
Events2 events2 = dte.Events as Events2;
if (events2 != null)
{
this.projectItemsEvents = events2.ProjectItemsEvents;
this.projectItemsEvents.ItemAdded += this.ProjectItemsEvents_ItemAdded;
this.projectItemsEvents.ItemRemoved += this.ProjectItemsEvents_ItemRemoved;
this.projectItemsEvents.ItemRenamed += this.ProjectItemsEvents_ItemRenamed;
}
this.csharpProjectItemsEvents =
dte.Events.GetObject("CSharpProjectItemsEvents") as ProjectItemsEvents;
if (this.csharpProjectItemsEvents != null)
{
this.csharpProjectItemsEvents.ItemAdded += this.CSharpProjectItemsEvents_ItemAdded;
this.csharpProjectItemsEvents.ItemRemoved += this.CSharpProjectItemsEvents_ItemRemoved;
this.csharpProjectItemsEvents.ItemRenamed += this.CSharpProjectItemsEvents_ItemRenamed;
}
The key to both was making sure to keep a reference to the events object in the subscriber. Once I added the reference, they behaved like I expected.
private ProjectItemsEvents projectItemsEvents;
private ProjectItemsEvents csharpProjectItemsEvents;
Check out this FAQ article which explains how to register for ProjectItems events (including ItemDeleted).