g++ bug?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

g++ bug?

Post 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)
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: g++ bug?

Post 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++.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
8infy
Member
Member
Posts: 185
Joined: Sun Apr 05, 2020 1:01 pm

Re: g++ bug?

Post 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
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: g++ bug?

Post 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. :!:
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
MichaelPetch
Member
Member
Posts: 797
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: g++ bug?

Post 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.
Post Reply