I wonder if you guys might be able to help me with a Technical issue
I have been writing a 32 bit operating system
When I come to the PIC and PIT reprogramming I started receiving an unexpected break operation, int 3
I reverse engineered the software to try and find the interrupt 3 call in assembly and have had no luck finding in the code itself
So I have assumed that the Interrupt is coming from the Hardware itself.
My question
Is it possible for the hardware to throw these interrupts ?
and how would one debug something like this ?
Thanks in advance
Jono
Reprogramming The Pic and Pit
- thepowersgang
- Member
- Posts: 734
- Joined: Tue Dec 25, 2007 6:03 am
- Libera.chat IRC: thePowersGang
- Location: Perth, Western Australia
- Contact:
Re: Reprogramming The Pic and Pit
My magic mindreading hat tells me that you have forgotten or failed to correctly remap the PIC and IRQ3 has just fired.
Make sure you remap the PIC to interrupts above 31 (I use 0xF0->0xFF)
Make sure you remap the PIC to interrupts above 31 (I use 0xF0->0xFF)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Re: Reprogramming The Pic and Pit
Hi,
As far as I know, it is possible to map IRQ 3 or IRQ 11 to interrupt 3 by mis-configuring a PIC chip. It's hard to accidentally remap PIC chips though, so this would be the result of either a "hard to make" bug or a something done intentionally (e.g. based on some sort of misunderstanding).
Also note that there are 2 different instructions that software could use to generate an "interrupt 3". There's the "int n" instruction and a special "int3" instruction. These are different (different opcodes and semantically different - "int n" is classed as a software interrupt while the "int3" is classed as an exception) but the result is mostly the same (except for how the CPU does protection checks in protected mode or long mode).
The first way is to install an interrupt handler for interrupt 3, and when the interrupt occurs look at the interrupt handler's "return CS" and "return IP". If the interrupt was caused by software this will tell you the address of the "int n" or "int 3" instruction. If the interrupt was caused by hardware then it won't.
The second way is a binary search - find somewhere in the middle of the code and insert an infinite loop, and see if the code crashes before this point (or locks up correctly) to determine if the problem is in the first half of the code or the second half. Then shift the infinite loop into the middle of the "problem half" and determine which quarter of the code causes the problem. Keep doing that to find which 8th of the code contains the problem, then which 16th, which 32nd, etc. Eventually you'll know exactly which piece of code is causing the problem.
The third way is to use a debugger (e.g. the debugger built into Bochs, Qemu, VirtualBox, etc) to watch exactly what is happenening (either by enabling tracing or single-stepping).
The fourth way is to think of anything that could cause the problem and eliminate the possibilities until you've found the problem. I'd immediately suspect the code you're using to remap/reconfigure the PIC chips as you've probably recently added this code (can you disable IRQs with "CLI" to see if it prevents the interrupt?). My next guess would be only loading part of your code into RAM (e.g. loading the first 5 sectors of a kernel that happened to grow larger than 5 sectors); so that when you think you're executing your code (that doesn't contain "int 3") you're actually executing garbage that does (can you inspect the memory with a debugger or something to see if your code is loaded correctly?). The next guess would be messing up the stack somehow, so that an IRET or RET or something causes the CPU to return to a dodgy address and execute garbage.
Cheers,
Brendan
In theory, it shouldn't be possible for MSI, the IO APIC or another CPU to send an "interrupt 3", because any vector from 0x00 to 0x001F is meant to be invalid for these. In practice it's possible that there's some hardware that fails to disallow it.Jono23 wrote:Is it possible for the hardware to throw these interrupts ?
As far as I know, it is possible to map IRQ 3 or IRQ 11 to interrupt 3 by mis-configuring a PIC chip. It's hard to accidentally remap PIC chips though, so this would be the result of either a "hard to make" bug or a something done intentionally (e.g. based on some sort of misunderstanding).
Also note that there are 2 different instructions that software could use to generate an "interrupt 3". There's the "int n" instruction and a special "int3" instruction. These are different (different opcodes and semantically different - "int n" is classed as a software interrupt while the "int3" is classed as an exception) but the result is mostly the same (except for how the CPU does protection checks in protected mode or long mode).
There's at least 4 ways.Jono23 wrote:and how would one debug something like this ?
The first way is to install an interrupt handler for interrupt 3, and when the interrupt occurs look at the interrupt handler's "return CS" and "return IP". If the interrupt was caused by software this will tell you the address of the "int n" or "int 3" instruction. If the interrupt was caused by hardware then it won't.
The second way is a binary search - find somewhere in the middle of the code and insert an infinite loop, and see if the code crashes before this point (or locks up correctly) to determine if the problem is in the first half of the code or the second half. Then shift the infinite loop into the middle of the "problem half" and determine which quarter of the code causes the problem. Keep doing that to find which 8th of the code contains the problem, then which 16th, which 32nd, etc. Eventually you'll know exactly which piece of code is causing the problem.
The third way is to use a debugger (e.g. the debugger built into Bochs, Qemu, VirtualBox, etc) to watch exactly what is happenening (either by enabling tracing or single-stepping).
The fourth way is to think of anything that could cause the problem and eliminate the possibilities until you've found the problem. I'd immediately suspect the code you're using to remap/reconfigure the PIC chips as you've probably recently added this code (can you disable IRQs with "CLI" to see if it prevents the interrupt?). My next guess would be only loading part of your code into RAM (e.g. loading the first 5 sectors of a kernel that happened to grow larger than 5 sectors); so that when you think you're executing your code (that doesn't contain "int 3") you're actually executing garbage that does (can you inspect the memory with a debugger or something to see if your code is loaded correctly?). The next guess would be messing up the stack somehow, so that an IRET or RET or something causes the CPU to return to a dodgy address and execute garbage.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Re: Reprogramming The Pic and Pit
Thanks Guys for the speedy replies and for the fresh ideas !
I Will definitely try that. I have been able to isolate the section of code that goes wrong.But I never though of checking the stack pointer and memory
You wouldn't perhaps have Know of a basic kernel I could use as a reference model especially with regards to the Pic and PIT ( preferably written in c++ )
Kindest Regard's
Jono
I Will definitely try that. I have been able to isolate the section of code that goes wrong.But I never though of checking the stack pointer and memory
You wouldn't perhaps have Know of a basic kernel I could use as a reference model especially with regards to the Pic and PIT ( preferably written in c++ )
Kindest Regard's
Jono