Does a GPF always push an error code?

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
User avatar
eryjus
Member
Member
Posts: 286
Joined: Fri Oct 21, 2011 9:47 pm
Libera.chat IRC: eryjus
Location: Tustin, CA USA

Does a GPF always push an error code?

Post by eryjus »

Hi,

I've read the Intel manual several times, and also reviewed the Exceptions wiki. Based on what I have read I would expect a GPF to always push an error code (though it might be 0).

As I mentioned in this post, I am trying to unwind an error and I have uncovered a stack alignment problem with a GPF. Here is an annotated Bochs log:

Code: Select all

========================================================================
                     Bochs x86 Emulator 2.6.6.svn
              Built from SVN snapshot after release 2.6.6
                  Compiled on Sep 30 2014 at 17:45:08
========================================================================
00000000000i[      ] set SIGINT handler to bx_debug_ctrlc_handler
Next at t=0
(0) [0x0000fffffff0] f000:fff0 (unk. ctxt): add byte ptr ds:[bx+si], al ; 0000
00000000000i[XGUI  ] Mouse capture off
<bochs:1> 00000000024d[CPU0  ] inhibit interrupts mask = 3
00000004661i[BIOS  ] $Revision: 12412 $ $Date: 2014-07-10 09:28:59 +0200 (Do, 10. Jul 2014) $
00000318049i[KBD   ] reset-disable command received
00000320303d[CPU0  ] protected mode activated
00000320308d[CPU0  ] inhibit interrupts mask = 3
00000320818i[BIOS  ] Starting rombios32
00000321256i[BIOS  ] Shutdown flag 0
00000321848i[BIOS  ] ram_size=0xc0000000
00000322344i[BIOS  ] ram_end=8192MB
<... snip ... />
00018168760i[BIOS  ] Booting from 07c0:0000
<... big snip ... />
00169892282d[CPU0  ] page walk for address 0xffff9000000000a9
00169951793d[CPU0  ] page walk for address 0xffffa000000b85b8
00169951810d[CPU0  ] page walk for address 0xffffa000000b85b8
00169951890d[CPU0  ] interrupt(): vector = 20, TYPE = 0, EXT = 1
00169951890d[CPU0  ] interrupt(long mode): INTERRUPT TO SAME PRIVILEGE
00169951928d[CPU0  ] LONG MODE IRET
00169952183d[CPU0  ] page walk for address 0xffffa00000000020
00169952309d[CPU0  ] page walk for address 0xffffa00000000020
00169952436d[CPU0  ] page walk for address 0xfffffff8010001c0
00169952478d[CPU0  ] page walk for address 0xfffff000000000a8
00169952610d[CPU0  ] page walk for address 0xfffff000000000a8
00169952761d[CPU0  ] page walk for address 0xfffffff8010001c0
00169952763d[CPU0  ] TLB_invlpg(0xfffff00200038000): invalidate TLB entry
00169952922d[CPU0  ] page walk for address 0xfffff000000000a8
00169953062d[CPU0  ] page walk for address 0xfffff000000000a8
00169953213d[CPU0  ] page walk for address 0xfffffff8010001c8
00169953215d[CPU0  ] TLB_invlpg(0xfffff00200039000): invalidate TLB entry
00169953374d[CPU0  ] page walk for address 0xfffff000000000a8
00169953522d[CPU0  ] page walk for address 0xfffff000000000a8
00169953673d[CPU0  ] page walk for address 0xfffffff8010001d0
00169953675d[CPU0  ] TLB_invlpg(0xfffff0020003a000): invalidate TLB entry
00169953834d[CPU0  ] page walk for address 0xfffff000000000a8
00169953990d[CPU0  ] page walk for address 0xfffff000000000a8
00169954141d[CPU0  ] page walk for address 0xfffffff8010001d8
00169954143d[CPU0  ] TLB_invlpg(0xfffff0020003b000): invalidate TLB entry
00169954311d[CPU0  ] page walk for address 0xfffff0020003bff8
00169954418d[CPU0  ] page walk for address 0xffff9000000000ae
00169954436d[CPU0  ] page walk for address 0x00000000000b8f00
00169954441d[CPU0  ] page walk for address 0xffff9000000000a9
00170013952d[CPU0  ] page walk for address 0xffffa000000b8660
00170013969d[CPU0  ] page walk for address 0xffffa000000b8660
00170014049d[CPU0  ] interrupt(): vector = 20, TYPE = 0, EXT = 1                      # -- Task swap takes place here (not really working on this yet)
00170014049d[CPU0  ] interrupt(long mode): INTERRUPT TO SAME PRIVILEGE
00170014087d[CPU0  ] LONG MODE IRET                                                   # -- This will be the cause of my GPF  (not working on this yet)
00170014120d[CPU0  ] interrupt(): vector = 0d, TYPE = 4, EXT = 0                      # -- This is the start of the GPF
00170014120d[CPU0  ] interrupt(long mode): INTERRUPT TO SAME PRIVILEGE
00170014122i[CPU0  ] [170014122] Stopped on MAGIC BREAKPOINT                          # -- This is the first thing (before pushing any additional registers) that happens in the handler
(0) Magic breakpoint
Next at t=170014122
(0) [0x00000010294b] 0008:ffff80000010294b (unk. ctxt): push rbp                  ; 55
00170014122i[XGUI  ] Mouse capture off

<bochs:2> reg                                                                         # -- get the register values -- looking to dump the stack

CPU0:
rax: 00000000_00000001 rcx: 00000000_00000010
rdx: 00000000_00000020 rbx: 00000000_e0000011
rsp: fffff002_00003fc8 rbp: 00000000_00000000
rsi: 00000000_00000000 rdi: 00000000_000b800c
r8 : 00000000_00000000 r9 : 00000000_00000000
r10: 00000000_00000000 r11: 00000000_00000000
r12: 00000000_00000000 r13: 00000000_00000000
r14: 00000000_00000000 r15: 00000000_00000000
rip: ffff8000_0010294b
eflags 0x00200086: ID vip vif ac vm rf nt IOPL=0 of df if tf SF zf af PF cf
00170014131i[XGUI  ] Mouse capture off

<bochs:3> x /14 0xffff00200003fc8                                                     # -- The contents of the entire stack

0x0ffff00200003fc8 <bogus+       0>:	0x00103f0e	0xffff8000	0x00000008	0x00000000
0x0ffff00200003fd8 <bogus+      16>:	0x00200286	0x00000000	0x00003ff8	0xfffff002
0x0ffff00200003fe8 <bogus+      32>:	0x00000010	0x00000000	0x000b8400	0xffffa000
0x0ffff00200003ff8 <bogus+      48>:	0x00000000	0x00000000
00170014122i[XGUI  ] Mouse capture off
<bochs:3> 00170014122i[      ] dbg: Quit
00170014122i[CPU0  ] CPU is in long mode (active)
00170014122i[CPU0  ] CS.mode = 64 bit
00170014122i[CPU0  ] SS.mode = 64 bit
00170014122i[CPU0  ] EFER   = 0x00000500
00170014122i[CPU0  ] | RAX=0000000000000001  RBX=00000000e0000011
00170014122i[CPU0  ] | RCX=0000000000000010  RDX=0000000000000020
00170014122i[CPU0  ] | RSP=fffff00200003fc8  RBP=0000000000000000
00170014122i[CPU0  ] | RSI=0000000000000000  RDI=00000000000b800c
00170014122i[CPU0  ] |  R8=0000000000000000   R9=0000000000000000
00170014122i[CPU0  ] | R10=0000000000000000  R11=0000000000000000
00170014122i[CPU0  ] | R12=0000000000000000  R13=0000000000000000
00170014122i[CPU0  ] | R14=0000000000000000  R15=0000000000000000
00170014122i[CPU0  ] | IOPL=0 ID vip vif ac vm rf nt of df if tf SF zf af PF cf
00170014122i[CPU0  ] | SEG sltr(index|ti|rpl)     base    limit G D
00170014122i[CPU0  ] |  CS:0008( 0001| 0|  0) 00000000 00000fff 1 0
00170014122i[CPU0  ] |  DS:0010( 0002| 0|  0) 00000000 00000fff 1 0
00170014122i[CPU0  ] |  SS:0010( 0002| 0|  0) 00000000 00000fff 1 0
00170014122i[CPU0  ] |  ES:0010( 0002| 0|  0) 00000000 00000fff 1 0
00170014122i[CPU0  ] |  FS:0010( 0002| 0|  0) 00000000 00000fff 1 0
00170014122i[CPU0  ] |  GS:0010( 0002| 0|  0) 00000000 00000fff 1 0
00170014122i[CPU0  ] |  MSR_FS_BASE:0000000000000000
00170014122i[CPU0  ] |  MSR_GS_BASE:0000000000000000
00170014122i[CPU0  ] | RIP=ffff80000010294b (ffff80000010294b)
00170014122i[CPU0  ] | CR0=0xe0000011 CR2=0x0000000000000000
00170014122i[CPU0  ] | CR3=0x00400000 CR4=0x00000020
(0).[170014122] [0x00000010294b] 0008:ffff80000010294b (unk. ctxt): push rbp                  ; 55
00170014122i[CMOS  ] Last time is 1421965664 (Thu Jan 22 15:27:44 2015)
00170014122i[XGUI  ] Exit
00170014122i[SIM   ] quit_sim called with exit code 0
OK, starting from the Top of the Stack...
0x8:ffff 8000 0010 3f0e is my CS:RIP return address
0x0000 0000 0020 0286 is my RFLAGS
0x10:ffff f002 0000 3ff8 is my SS:RSP stack for the IRETQ fro the GPF
(Below that on the stack is my other problem which I will work on soon)

What I don't see is the error code for the GPF... I don't want to blame the tool (and I'm getting the same stack alignment problem in QEMU as well). But my observations are not matching the documentation. Any thoughts on what might be causing this?

BTW: Per Combuster's recommendation in the above post, I did change my code so that neither the IRQ0 nor the GPF does not use an IST; and since I am not changing privileges yet, everything should be piled on the same stack.

Thanks in advance for your replies.
Adam

The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal

"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Does a GPF always push an error code?

Post by Brendan »

Hi,

There are only 3 cases where GPF doesn't give you an error code:
  • You're in real mode.
  • It's not a GPF and it's actually an IRQ
  • It's not a GPF and it's actually a software interrupt
eryjus wrote:(Below that on the stack is my other problem which I will work on soon)
Could that other problem have involved executing random stuff that may have included the bytes "0xCD, 0x0D"? ;)


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.
User avatar
eryjus
Member
Member
Posts: 286
Joined: Fri Oct 21, 2011 9:47 pm
Libera.chat IRC: eryjus
Location: Tustin, CA USA

Re: Does a GPF always push an error code?

Post by eryjus »

Well...... :oops: :oops: :oops:

I think this just might be the cause:

Code: Select all

.loop:          push        0
                int         13

                hlt
                jmp         .loop
I left some test code and walked away for about a week. Turn out I forgot I left it in there.

And I also just realized my test was WRONG anyway!!! It might have been a good thing to step away for awhile...

Thanks, Brendan!
Adam

The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal

"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
Post Reply