Page 1 of 1

g++ bug?

Posted: Sun May 24, 2020 6:19 am
by 8infy
Today I was working on setting up interrupt handling for my OS and encountered a crazy g++ bug (or maybe I made a mistake?).

I set up IDT and ISRs entirely from .cpp files, here are a few screenshots:

Macros to generate an assembly entry for the isr
Image

InterruptServiceRoutines class: (USED is __attribute__((used)), g++ seems to omit the symbol otherwise)
Image

How I use it in my c++ code
(The NO_ERROR_CODE macro is the same as on the first screenshot, the only difference is that it does pushl 0 in the beginning)
Image

As you can see in the third screenshot I have a stub, if I remove it the first defined interrupt handler turns into a NULL
So in this case if I remove the stub, the address of division_by_zero_entry (NOT HANDLER!) is 0x00000000, I see it in the
debugger as well. Every other isr has the correct address and I verified it multiple times. If I change the order around, any other
isr (like debug_handler) becomes NULL and division_by_zero_entry becomes a valid address!

With stub: (IDT table from Bochs debugger)
Image

Without the stub the first entry becomes 0x0008:0x00000000

If you need any more information please let me know!

EDIT: Now that i'm trying to reproduce it I can't anymore... Any ideas why it happened before? I'm sure everything else was correct, because I was getting double faulted as expected. (from not remapping the PIC)

Re: g++ bug?

Posted: Sun May 24, 2020 6:29 am
by nexos
My guess would be you were using inline assembly for your ISR stub. The optimizer may "optimize" the code in a way that results in strange bugs. If you continue with inline ASM, you will be constantly dealing with bugs. I recommend switching to using external assembly files. My ISR stub file is at https://github.com/NexSuite/NexNix/blob ... _stubs.asm. Feel free to use it however you wish. You could also use __attribute__((interrupt)) before the function name. I'm not sure if this is in g++.

Re: g++ bug?

Posted: Sun May 24, 2020 7:57 am
by 8infy
nexos wrote:My guess would be you were using inline assembly for your ISR stub. The optimizer may "optimize" the code in a way that results in strange bugs. If you continue with inline ASM, you will be constantly dealing with bugs. I recommend switching to using external assembly files. My ISR stub file is at https://github.com/NexSuite/NexNix/blob ... _stubs.asm. Feel free to use it however you wish. You could also use __attribute__((interrupt)) before the function name. I'm not sure if this is in g++.
Thanks, I might do something like this as well

Re: g++ bug?

Posted: Sun May 24, 2020 11:25 am
by Octacone
nexos wrote:...If you continue with inline ASM, you will be constantly dealing with bugs. I recommend switching to using external assembly files...
Couldn't agree more. This definitely. :!:

Re: g++ bug?

Posted: Mon May 25, 2020 8:00 am
by MichaelPetch
I noticed at least for the code in the screenshots that the stubs are not inside of C functions. They are all basic inline assembly at global scope. Basic inline assembly has no optimizations applied to them, nor are they these stubs surrounded by C function prologue and epilogue.

I'm not fond of the interrupt attribute because it too is limited and has deficiencies. If you ever want your C code to access the contents of a register as they appeared at the time of the interrupt, there is currently no reliable way to do it with this mechanism. This would be handy if you were writing a software interrupt and needed access to the registers to determine what actions to take (ie: int 0x80 on Linux). Another example would be to allow an interrupt to dump all the register contents to the display for debug purposes.