EEVBlog - A Really Basic GCC Compiler Bug! - Page 1
Forum section: electronics / general

author: Psi
author_rank: Super Contributor
timestamp: September 06, 2019, 04:07:57 am
content: My money is also on what others have said in the comments.USB stack unexpectedly running some of his code in interrupt land through callbacks or whatever.But it's tricky to see what's being called from where in the video without full copy of source.

author: firewalker
author_rank: Super Contributor
timestamp: September 06, 2019, 07:42:03 am
content: The code is in an ISR? It should volatile.Alexander.

author: hamster_nz
author_rank: Super Contributor
timestamp: September 06, 2019, 08:15:37 am
content: There is a bit of confusion there. 'being a register' has nothing to do with it.I think confusion is between a 'callback' that occurs within the main thread of program execution, and a 'callback' that is called asynchronously, from a signal or an interrupt (or maybe from another thread or task, or maybe it is a hardware register being updated by the hardware...).Not a GCC bug, but a bug in the writers mental model of what is going on vs what they have told the compiler what to expect.

author: Psi
author_rank: Super Contributor
timestamp: September 06, 2019, 09:45:56 am
content: Different mcu, but i've had similar issues where the peripheral library runs your code in interrupt land without it being clear in the documentation that it will do that.

author: thm_w
author_rank: Super Contributor
timestamp: September 06, 2019, 09:10:11 pm
content: This might be possible to catch via static analysis, but I don't know if a tool exists. It would have to be aware of interrupts. That or a compiler plug-in to highlight it.

author: coppice
author_rank: Super Contributor
timestamp: September 06, 2019, 09:33:52 pm
content: The majority of bugs reported against compilers are actually broken source code, just like this case. Some people are much too quick to blame someone else.

author: nctnico
author_rank: Super Contributor
timestamp: September 06, 2019, 10:14:12 pm
content: Quote from: firewalker on September 06, 2019, 07:42:03 amNot necessarily. You only need volatile if you are checking a variable in a loop. Like while (var_used_in_an_interrupt!=different_value) {keep_waiting();}; If you do the actual polling from a function you probably won't need volatile at all but a caveat can be that a function is inlined into the calling function. This will depend on the optimisation settings. Basically you need to know at which point a variable is read from memory into a register to determine whether you need volatile or not.

author: hamster_nz
author_rank: Super Contributor
timestamp: September 06, 2019, 10:29:29 pm
content: Quote from: nctnico on September 06, 2019, 10:14:12 pm.... until you turn the optimizer on and it inlines a function.Rule of thumb... if you expect that a value will change through something other than the obvious natural flow of execution through the code, then YOU needs to tell the compiler that it is volatile.

author: coppice
author_rank: Super Contributor
timestamp: September 06, 2019, 11:20:02 pm
content: Quote from: nctnico on September 06, 2019, 10:14:12 pmYouprobablywon't need voltaile? What kind of broken engineering strategy is that? This is how we end up with so many wrong bug reports against compilers. "It works OK with optimisation off, but fails with optimisation on, so your compiler is broken. Fix it.". Its amazing how much broken codes works OK until a new version of the compiler comes out, ups the game in optimisation, and makes the code behave as badly as it was written.I've seen open source projects rally around the idea that a broken GCC means some aspect of the code doesn't work, and this idea persists for years unquestioned. Then you look at the code one day, to wile away some time, make a couple of minor changes to tighten up things like the use of volatile, and suddenly the code works. Then, half the people STILL say it was the compiler at fault.

author: nctnico
author_rank: Super Contributor
timestamp: September 06, 2019, 11:30:26 pm
content: Quote from: coppice on September 06, 2019, 11:20:02 pmPerhaps you should very carefully read (again) what I wrote because I outlined the conditions precisely. One of the downsides of using volatile is that the resulting machine code will always read the memory and not store a value into a register. This in turn will result in slower code execution.

author: coppice
author_rank: Super Contributor
timestamp: September 06, 2019, 11:34:30 pm
content: Quote from: nctnico on September 06, 2019, 11:30:26 pmWe are looking at a situation where weneedto always read the memory for correct operation. Either you need that or you don't. "Probably" needing it is a ludicrous claim.

author: hamster_nz
author_rank: Super Contributor
timestamp: September 06, 2019, 11:49:18 pm
content: If you want to do it right and explicitly avoid that performance problem...volatile int volatile_x;void foo() {Int cached_x;cached_x = volatile_x;for(I = 0: i != cached_x; i++)bar(i) ;}Anything else is a path to a really shitty bug.For example, if you use volatile_x in the for loop, what happens in volatile_x changes from 1000 to 100 while i has only counted to 500?

author: nctnico
author_rank: Super Contributor
timestamp: September 07, 2019, 12:32:43 am
content: Quote from: hamster_nz on September 06, 2019, 11:49:18 pmAnd that is exactly why I came back to this thread. The problem Dave2 has may not even be related to using volatile. Making variables volatile may just alter the timing enough for the problem not to manifest itself. The real problem may be that while reading or writing new data from/to the USB buffer an interrupt changes the value. A better approach would be to disable the USB interrupts (as a kind of mutex) while performing operations on the USB data from user space. The LUFA USB stack has similar issues which are only solved by using a mutex (in that case also disabling the interrupts).