Bug in Visual Studio 2005 compiler?
-
Have you defined your own version of
max()
or are you using the one provided in some windows header? If the former, try commenting out that function and see if it still compiles in debug and/or release. If the latter, try defining your own function and see if it does compile in debug and/or release. As an alternative to either of the above you can try and#define NOMINMAX
before including windows.h . This will prevent the macro definitions formin()
andmax()
. These suggestions are based on the fact that MS provides macros formin()
andmax()
in some Windows header, and that these macros might mess up code in unexpected ways. I know it did breakstd::valarray::min()
andstd::valarray::max()
in VS 2003, and it did breakstd::min
andstd::max
in later versions, until MS eventually fixed it.GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
Thanks, boys, for yours comments, but I've just found the reason. And it did not make me happy. Really, great knowledge means great pain. Look at this small part of a stack frame: _lrct$ = -212 ; size = 16 tv5476 = -204 ; size = 8 Do you see something interesting here? A RECT structure of size 16 bytes and something too close to it- in fact, variable tv5476 partially overlaps RECT. And what command fst QWORD PTR tv5476[ebp] does? It rewrites half of my RECT. I can only hope, that it is the bug in my own Visual Studio. I'll reinstall it- may be, it will help (once I met something like tis- a "new" operator refused to work at all and re installation resolved this situation)
-
Thanks, boys, for yours comments, but I've just found the reason. And it did not make me happy. Really, great knowledge means great pain. Look at this small part of a stack frame: _lrct$ = -212 ; size = 16 tv5476 = -204 ; size = 8 Do you see something interesting here? A RECT structure of size 16 bytes and something too close to it- in fact, variable tv5476 partially overlaps RECT. And what command fst QWORD PTR tv5476[ebp] does? It rewrites half of my RECT. I can only hope, that it is the bug in my own Visual Studio. I'll reinstall it- may be, it will help (once I met something like tis- a "new" operator refused to work at all and re installation resolved this situation)
I think you are reading that the wrong way round. The variable
tv5476
is 8 bytes long starting at offset-204
, so it goes from -204 to -212. The variable_lrct$
is 16 bytes from-212
to -228. Your problem is much more likely to be a bug in your code that only shows up in the release version, and that is far from uncommon. [edit] OK, my shoulders are broad enough to admit that I was wrong with that first statement. Lack of coffee/gin. [/edit]Veni, vidi, abiit domum
-
I think you are reading that the wrong way round. The variable
tv5476
is 8 bytes long starting at offset-204
, so it goes from -204 to -212. The variable_lrct$
is 16 bytes from-212
to -228. Your problem is much more likely to be a bug in your code that only shows up in the release version, and that is far from uncommon. [edit] OK, my shoulders are broad enough to admit that I was wrong with that first statement. Lack of coffee/gin. [/edit]Veni, vidi, abiit domum
Richard MacCutchan wrote:
Your problem is much more likely to be a bug in your code that only shows up in the release version, and that is far from uncommon.
Yes. :thumbsup: However his actual code, like his I/O values are 'top secret'.
Veni, vidi, vici.
-
Richard MacCutchan wrote:
Your problem is much more likely to be a bug in your code that only shows up in the release version, and that is far from uncommon.
Yes. :thumbsup: However his actual code, like his I/O values are 'top secret'.
Veni, vidi, vici.
-
You, boys, made my face red. Not because of me- you even do not know assembler. Command like mov [ebp-4], eax rewrites bytes from [ebp-4] UP to [ebp-1] . Just as fst QWORD PTR [ebp-204] does. RECT was allocated at [ebp-212], therefore its 16 bytes occupied addresses from ebp-212 to ebp-196. So simple. And aforementioned fst overwrote half of them. And BTW, I saw the whole process under debugger. My recommendation- any boy, who pretended to be a pro, must know assembler. I know what the mainstream in programming is- to replace pros by cheap yesterdays scholars. And it really does not me happy.
-
You, boys, made my face red. Not because of me- you even do not know assembler. Command like mov [ebp-4], eax rewrites bytes from [ebp-4] UP to [ebp-1] . Just as fst QWORD PTR [ebp-204] does. RECT was allocated at [ebp-212], therefore its 16 bytes occupied addresses from ebp-212 to ebp-196. So simple. And aforementioned fst overwrote half of them. And BTW, I saw the whole process under debugger. My recommendation- any boy, who pretended to be a pro, must know assembler. I know what the mainstream in programming is- to replace pros by cheap yesterdays scholars. And it really does not me happy.
-
Jolly good for you. You obviously won't need any help from us in the future then.
Veni, vidi, abiit domum
I need help. Question is, if any of you can give me some more or less valuable tip. When I asked my question the first time, I was not sure, that a bug really presents in Visual Studio. Now I know it. Problem is, what I have to do in such sorrowful situation. If someone else met such problem and fixed it, such person could share his experience. May be, this bug presents only in my own exemplar of Visual Studio- may be, it was damaged in some way and produces code with defects- in such case re-installation will solve this problem. Or such bug presents in each exemplar of Visual Studio 2005- in such case, I have to throw it away and buy 2008 or 2010. I know about a bug in Borland's compiler.
-
I need help. Question is, if any of you can give me some more or less valuable tip. When I asked my question the first time, I was not sure, that a bug really presents in Visual Studio. Now I know it. Problem is, what I have to do in such sorrowful situation. If someone else met such problem and fixed it, such person could share his experience. May be, this bug presents only in my own exemplar of Visual Studio- may be, it was damaged in some way and produces code with defects- in such case re-installation will solve this problem. Or such bug presents in each exemplar of Visual Studio 2005- in such case, I have to throw it away and buy 2008 or 2010. I know about a bug in Borland's compiler.
a_matseevsky wrote:
I need help.
Then you could start by showing the actual code that is going wrong, as raised in your original question. Also you need to show the exact values of the variables that cause the problems, and the actual and expected result values.
Veni, vidi, abiit domum
-
a_matseevsky wrote:
I need help.
Then you could start by showing the actual code that is going wrong, as raised in your original question. Also you need to show the exact values of the variables that cause the problems, and the actual and expected result values.
Veni, vidi, abiit domum
I did it. Problem was caused by incorrect allocation of local variables in stack frame. This is what I hardly can change- it is a bug in compiler. The only important fact is that one value was replaced by another. Exact values of variables here mean nothing.
-
I did it. Problem was caused by incorrect allocation of local variables in stack frame. This is what I hardly can change- it is a bug in compiler. The only important fact is that one value was replaced by another. Exact values of variables here mean nothing.
If you continue to refuse to provide the information we have asked for, then there is no way we can offer any suggestions as to what may be wrong. If you are convinced that this is a compiler bug then you should collect all the information and send it to Microsoft.
Veni, vidi, abiit domum
-
If you continue to refuse to provide the information we have asked for, then there is no way we can offer any suggestions as to what may be wrong. If you are convinced that this is a compiler bug then you should collect all the information and send it to Microsoft.
Veni, vidi, abiit domum
I clearly demonstrated, what cased problem in particular. I can repeat it again. There was two local variables: _lrct$ = -212 ; size = 16 tv5476 = -204 ; size = 8 The next command rewrites 8 bytes of _lrct$ fst QWORD PTR tv5476[ebp] That's all info. Which data in particular was replaced and by what- means nothing. The only important fact is that data was replaced with something else.
-
I clearly demonstrated, what cased problem in particular. I can repeat it again. There was two local variables: _lrct$ = -212 ; size = 16 tv5476 = -204 ; size = 8 The next command rewrites 8 bytes of _lrct$ fst QWORD PTR tv5476[ebp] That's all info. Which data in particular was replaced and by what- means nothing. The only important fact is that data was replaced with something else.
-
I have a solid guess, that it is a bug in compiler. Look at the next code: int xmin=max(xl1, max(xl2, xl3)); It works fine in the debug version, but gives me some nonsense in the release one. At that very time this variant works properly in both versions: int xmin=xl1; if(xmin
a_matseevsky wrote:
Any idea how could it be?
Perhaps nonstandard compiler options or linker options. And I am rather certain that max() is a macro. Which means that the only possible source of the problem would be an optimization. Excluding of course some pointer bug, which could cause almost any problem. And I am also certain that you could write a trivially small program that would demonstrate this, which is basically what has already been asked. If you cannot in fact demonstrate the same problem with the trivial program then it would point to some other problem in your application.
-
a_matseevsky wrote:
Any idea how could it be?
Perhaps nonstandard compiler options or linker options. And I am rather certain that max() is a macro. Which means that the only possible source of the problem would be an optimization. Excluding of course some pointer bug, which could cause almost any problem. And I am also certain that you could write a trivially small program that would demonstrate this, which is basically what has already been asked. If you cannot in fact demonstrate the same problem with the trivial program then it would point to some other problem in your application.
There is no way to demonstrate problem, if compiler is unstable. problem disappeared, when I replaced max() and min(), but occurred again after some insignificant change in code (which was made far from the procedure, where problem occurred!). I used default compiler's options. Later, when I was looking for the source of the problem, I created database and set /Zi switch for the release version. After these actions I was able to find the very command, which destroyed my data. The next was trivial- I find offsets of local variables and noticed, that some of them was incorrectly placed (one partially overlaps another). This is the bug in compiler, not mine.
-
There is no way to demonstrate problem, if compiler is unstable. problem disappeared, when I replaced max() and min(), but occurred again after some insignificant change in code (which was made far from the procedure, where problem occurred!). I used default compiler's options. Later, when I was looking for the source of the problem, I created database and set /Zi switch for the release version. After these actions I was able to find the very command, which destroyed my data. The next was trivial- I find offsets of local variables and noticed, that some of them was incorrectly placed (one partially overlaps another). This is the bug in compiler, not mine.
-
a_matseevsky wrote:
This is the bug in compiler, not mine.
Then go and tell Microsoft about it, as I already suggested, since you refuse to show us any of the code which causes the problem.
Veni, vidi, abiit domum
I will. I've just registered at M$'s site. And I got you all info to understand, where the problem is. For me situation is clear. What I got, running release under debugger: lrct {top=30 bottom=958 left=162 right=750} 0041A88F fst qword ptr [ebp-0D4h] lrct {top=30 bottom=1080213504 left=162 right=0} Here you may see, what made one single command- RECT structure before and after this command. What additional info do you need? Prefix "tv" definitely means Temporarily Variables. This variable was placed too close to storage of RECT structure and fst overwrote it. If you cannot see it, I wash my hands. If you do not know, which bytes fst overwrite, sorry, man- there are problems, which obviously cannot be solved at the level of source code. One must dig deeper. And to do it, you must know many things, like assembler, structure of stack frame and so on and so on. (lrct was stored at ebp-0DCh)
-
I will. I've just registered at M$'s site. And I got you all info to understand, where the problem is. For me situation is clear. What I got, running release under debugger: lrct {top=30 bottom=958 left=162 right=750} 0041A88F fst qword ptr [ebp-0D4h] lrct {top=30 bottom=1080213504 left=162 right=0} Here you may see, what made one single command- RECT structure before and after this command. What additional info do you need? Prefix "tv" definitely means Temporarily Variables. This variable was placed too close to storage of RECT structure and fst overwrote it. If you cannot see it, I wash my hands. If you do not know, which bytes fst overwrite, sorry, man- there are problems, which obviously cannot be solved at the level of source code. One must dig deeper. And to do it, you must know many things, like assembler, structure of stack frame and so on and so on. (lrct was stored at ebp-0DCh)
a_matseevsky wrote:
there are problems, which obviously cannot be solved at the level of source code
But without the source code it is impossible to understand the structure of the program or why these variables are being allocated the way they are. You keep saying you have given us all the information but all you have shown is two or three lines of assembler without any context, so there is no way we can begin to understand what is happening or why. I must confess I am at a total loss to understand why you refuse to provide the information that we have asked for so we can try and help you.
Veni, vidi, abiit domum
-
a_matseevsky wrote:
there are problems, which obviously cannot be solved at the level of source code
But without the source code it is impossible to understand the structure of the program or why these variables are being allocated the way they are. You keep saying you have given us all the information but all you have shown is two or three lines of assembler without any context, so there is no way we can begin to understand what is happening or why. I must confess I am at a total loss to understand why you refuse to provide the information that we have asked for so we can try and help you.
Veni, vidi, abiit domum
You cannot help me. How could you help me, if you even do not know, which bytes overwrites fst command? I do not send my procedure only because of its size. And I know now, where the problem is. Well, if you think that the problem is in my code, look at two small pieces and try to understand, why and which one works properly, but the other does not. I fixed the problem (well, not completely- I only rewrote my code, using my knowledge about compiler's incorrect behavior. lrct was removed at all.) Variant A: int xmin=xf+(fct*pdpr->m_croprect[Right].left-xf-ddi)*(xl-xf)/(yr1-yr0); int xmax=xl+(fct*pdpr->m_croprect[Left].right-xl)*(xl-xf)/(yl1-yl0); h=0.5*pdpr->m_croprect[Left].top+0.5*pdpr->m_croprect[Left].bottom; pdpr->GetKorrHorz2D(xfirst, xlast, Dv, Dh, h, ddi, yh, yv, yhs, yvs, pKorr, ph, pv); pdpr->GetCorrLineH2(xfirst, xlast, h, ddi, yh, yv, yh, yv, ph, pv, 0, 0); yl0=xf+0.5*yh[xf]; yl1=xl+0.5*yh[xl]; yr0=xf+ddi-0.5*yh[xf]; yr1=xl+ddi-0.5*yh[xl]; int xl2=xf+(fct*pdpr->m_croprect[Right].left-xf-ddi)*(xl-xf)/(yr1-yr0); if(xl2>xmin) xmin=xl2; int xr2=xl+(fct*pdpr->m_croprect[Left].right-xl)*(xl-xf)/(yl1-yl0); if(xmax>xr2) xmax=xr2; h=0.1*pdpr->m_croprect[Left].top+0.9*pdpr->m_croprect[Left].bottom; pdpr->GetKorrHorz2D(xfirst, xlast, Dv, Dh, h, ddi, yh, yv, yhs, yvs, pKorr, ph, pv); pdpr->GetCorrLineH2(xfirst, xlast, h, ddi, yh, yv, yh, yv, ph, pv, 0, 0); yl0=xf+0.5*yh[xf]; yl1=xl+0.5*yh[xl]; yr0=xf+ddi-0.5*yh[xf]; yr1=xl+ddi-0.5*yh[xl]; int xl3=xf+(fct*pdpr->m_croprect[Right].left-xf-ddi)*(xl-xf)/(yr1-yr0); if(xl3>xmin) xmin=xl3; int xr3=xl+(fct*pdpr->m_croprect[Left].right-xl)*(xl-xf)/(yl1-yl0); if(xmax>xr3) xmax=xr3; xfirst=xmin+0.02*(xmax-xmin); xlast=xmax-0.02*(xmax-xmin); Variant B: int xl1=xf+(fct*pdpr->m_croprect[Right].left-xf-ddi)*(xl-xf)/(yr1-yr0); int xr1=xl+(fct*pdpr->m_croprect[Left].right-xl)*(xl-xf)/(yl1-yl0); h=0.5*pdpr->m_croprect[Left].top+0.5*pdpr->m_croprect[Left].bottom; pdpr->GetKorrHorz2D(xfirst, xlast, Dv, Dh, h, ddi, yh, yv, yhs, yvs, pKorr, ph, pv); pdpr->GetCorrLineH2(xfirst, xlast, h, ddi, yh, yv, yh, yv, ph, pv, 0, 0); yl0=xf+0.5*yh[xf]; yl1=xl+0.5*yh[xl]; yr0=xf+ddi-0.5*yh[xf]; yr1=xl+ddi-0.5*yh[xl]; int xl2=xf+(fct*pdpr->m_croprect[Right].left-xf-ddi)*(xl-xf)/(yr1-yr0); int xr2=xl+(fct*pdpr->m_croprect[Left].right-xl)*(xl-xf)/(yl1-yl0); h=0.1*pdpr->m_croprect[Left].top+0.9*pdpr->m_croprect[Left].bottom; pdpr->GetKorrHorz2D(xfirst, xlast, D
-
There is no way to demonstrate problem, if compiler is unstable. problem disappeared, when I replaced max() and min(), but occurred again after some insignificant change in code (which was made far from the procedure, where problem occurred!). I used default compiler's options. Later, when I was looking for the source of the problem, I created database and set /Zi switch for the release version. After these actions I was able to find the very command, which destroyed my data. The next was trivial- I find offsets of local variables and noticed, that some of them was incorrectly placed (one partially overlaps another). This is the bug in compiler, not mine.
a_matseevsky wrote:
There is no way to demonstrate problem, if compiler is unstable. problem disappeared
Compilers are not "unstable" in the way you are suggesting. If the environment is the same and stable and the compiler is same and the source (and build environment) is the same then excluding so runtime constants such as timestamps and hashes the output is the same.
a_matseevsky wrote:
when I replaced max() and min(), but occurred again after some insignificant change in code (which was made far from the procedure, where problem occurred!)....This is the bug in compiler, not mine.
Sorry then but that statement suggests that there is no other possible reason except that you have a pointer bug. Your application is misusing something somewhere. The nature of max and what it does in terms of integers has not changed in years. One can't do much more in terms of optimizations with it, since for the most part it is the how the integers themselves are located and not the execution that can be optimized (and I only mention that because optimization was the only other explanation.) However pointer bugs can impact almost anything in the application. And although a pointer bug might cause a problem where the actual pointer is in use it can in fact only show up far from the buggy code. (And I know this from experience not conjecture.) It also doesn't need to reflect anything in the code that you changed in that it doesn't need to have a pointer in it. What matters is that you changed the execution path (by definition that is what code changes mean) and because of that something that could have been a bug but undetected for months or even years now causes some unexpected failure. And I want to emphasize again that the pointer bug could be anywhere. The behavior you are seing is a symptom not a cause.
-
a_matseevsky wrote:
There is no way to demonstrate problem, if compiler is unstable. problem disappeared
Compilers are not "unstable" in the way you are suggesting. If the environment is the same and stable and the compiler is same and the source (and build environment) is the same then excluding so runtime constants such as timestamps and hashes the output is the same.
a_matseevsky wrote:
when I replaced max() and min(), but occurred again after some insignificant change in code (which was made far from the procedure, where problem occurred!)....This is the bug in compiler, not mine.
Sorry then but that statement suggests that there is no other possible reason except that you have a pointer bug. Your application is misusing something somewhere. The nature of max and what it does in terms of integers has not changed in years. One can't do much more in terms of optimizations with it, since for the most part it is the how the integers themselves are located and not the execution that can be optimized (and I only mention that because optimization was the only other explanation.) However pointer bugs can impact almost anything in the application. And although a pointer bug might cause a problem where the actual pointer is in use it can in fact only show up far from the buggy code. (And I know this from experience not conjecture.) It also doesn't need to reflect anything in the code that you changed in that it doesn't need to have a pointer in it. What matters is that you changed the execution path (by definition that is what code changes mean) and because of that something that could have been a bug but undetected for months or even years now causes some unexpected failure. And I want to emphasize again that the pointer bug could be anywhere. The behavior you are seing is a symptom not a cause.
I can only recommend to you reread the whole discussion. I do know now, where the problem is. OK, compiler is absolutely stable. No problem with it. But it works incorrectly. It reserves some places in a stack for temporary variables. In fact, these variables stores content of co-processor's registers. Some of such temporary variables overlap (partially or completely) another local variables. It might be no problem- some local variables are visible only within some block, not within the whole procedure. If execution of code leaves some block (part of code within such {} brackets), all variables, declared within this block, becomes inaccessible and their place in a stack may be rewritten by another local variable. But compiler creates exe file, which performs this op even when some local variable is visible and accessible!!! And it happens not only with RECT structure, but with some of other local variables too. I saw this process, when I was running release version under debugger. Look up, where I placed piece of my code. Variable "h" was rewritten at least once. If it is not a compiler's bug, I'm definitely an elefant.