Author Topic: EEVBlog - A Really Basic GCC Compiler Bug!  (Read 2659 times)

0 Members and 1 Guest are viewing this topic.

Offline PsiTopic starter

  • Super Contributor
  • ***
  • Posts: 9930
  • Country: nz
EEVBlog - A Really Basic GCC Compiler Bug!
« on: September 06, 2019, 04:05:25 am »
« Last Edit: September 06, 2019, 04:11:15 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline PsiTopic starter

  • Super Contributor
  • ***
  • Posts: 9930
  • Country: nz
Re: EEVBLOG - A Really Basic GCC Compiler Bug!
« Reply #1 on: September 06, 2019, 04:07:57 am »
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.
« Last Edit: September 06, 2019, 04:13:46 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 
The following users thanked this post: Kilrah

Offline firewalker

  • Super Contributor
  • ***
  • Posts: 2450
  • Country: gr
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #2 on: September 06, 2019, 07:42:03 am »
The code is in an ISR? It should  volatile.

Alexander.
« Last Edit: September 06, 2019, 07:44:52 am by firewalker »
Become a realist, stay a dreamer.

 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #3 on: September 06, 2019, 08:15:37 am »
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.
« Last Edit: September 06, 2019, 09:10:18 am by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: Kilrah, nugglix

Offline PsiTopic starter

  • Super Contributor
  • ***
  • Posts: 9930
  • Country: nz
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #4 on: September 06, 2019, 09:45:56 am »
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.
Greek letter 'Psi' (not Pounds per Square Inch)
 
The following users thanked this post: Kilrah

Offline thm_w

  • Super Contributor
  • ***
  • Posts: 6349
  • Country: ca
  • Non-expert
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #5 on: September 06, 2019, 09:10:11 pm »
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.
Profile -> Modify profile -> Look and Layout ->  Don't show users' signatures
 

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8637
  • Country: gb
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #6 on: September 06, 2019, 09:33:52 pm »
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.
 
The following users thanked this post: Kilrah, nugglix

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26891
  • Country: nl
    • NCT Developments
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #7 on: September 06, 2019, 10:14:12 pm »
The code is in an ISR? It should  volatile.

Alexander.
Not 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.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #8 on: September 06, 2019, 10:29:29 pm »
The code is in an ISR? It should  volatile.

Alexander.
Not 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.

.... 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.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: thm_w, Fungus, Jacon

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8637
  • Country: gb
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #9 on: September 06, 2019, 11:20:02 pm »
The code is in an ISR? It should  volatile.

Alexander.
Not 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.
You probably  won'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.
 
The following users thanked this post: nugglix

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26891
  • Country: nl
    • NCT Developments
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #10 on: September 06, 2019, 11:30:26 pm »
The code is in an ISR? It should  volatile.

Alexander.
Not 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.
You probably  won'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.
Perhaps 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.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8637
  • Country: gb
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #11 on: September 06, 2019, 11:34:30 pm »
The code is in an ISR? It should  volatile.

Alexander.
Not 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.
You probably  won'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.
Perhaps 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.
We are looking at a situation where we need to always read the memory for correct operation. Either you need that or you don't. "Probably" needing it is a ludicrous claim.
 
The following users thanked this post: Fungus, nugglix

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #12 on: September 06, 2019, 11:49:18 pm »
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?
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: Kilrah

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26891
  • Country: nl
    • NCT Developments
Re: EEVBlog - A Really Basic GCC Compiler Bug!
« Reply #13 on: September 07, 2019, 12:32:43 am »
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?
And 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).
« Last Edit: September 07, 2019, 12:34:15 am by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf