Jumping into infinite loop when mapping virtual address

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.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Jumping into infinite loop when mapping virtual address

Post by iansjack »

I think what Octocontrabass was asking is what assembly instruction is being executed when the program "stops". And what, exactly, do you mean by saying it stops - is it looping, as your question suggests, waiting on a hot instruction, or is the cpu double-faulting and restarting? (I can't think of any other interpretation of "stops", but there may be yet another meaning.)
NeonLightions
Member
Member
Posts: 102
Joined: Wed Oct 20, 2021 6:00 pm
Location: Paraguay

Re: Jumping into infinite loop when mapping virtual address

Post by NeonLightions »

iansjack wrote:I think what Octocontrabass was asking is what assembly instruction is being executed when the program "stops". And what, exactly, do you mean by saying it stops - is it looping, as your question suggests, waiting on a hot instruction, or is the cpu double-faulting and restarting? (I can't think of any other interpretation of "stops", but there may be yet another meaning.)
Can I know which instruction was excuted with GDB?
NeonLightions
Member
Member
Posts: 102
Joined: Wed Oct 20, 2021 6:00 pm
Location: Paraguay

Re: Jumping into infinite loop when mapping virtual address

Post by NeonLightions »

iansjack wrote:I think what Octocontrabass was asking is what assembly instruction is being executed when the program "stops". And what, exactly, do you mean by saying it stops - is it looping, as your question suggests, waiting on a hot instruction, or is the cpu double-faulting and restarting? (I can't think of any other interpretation of "stops", but there may be yet another meaning.)
I have used QEMU to debug this issue, and the last instruction it did is:

Code: Select all

0x00000001:  ff 00                    incl     (%eax)
0x00000003:  f0                       .byte    0xf0
0x00000004:  53                       pushl    %ebx
0x00000005:  ff 00                    incl     (%eax)
0x00000007:  f0                       .byte    0xf0
0x00000008:  c3                       retl  
I think that is the address after mapped with paging.
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Jumping into infinite loop when mapping virtual address

Post by iansjack »

Well, that looks like you are trying to run the real mode interrupt vector table as code! Somehow your eip is being set to zero - probably as a result of stack corruption somewhere. Does a stack backtrack at the point of failure give you any clues? You could try running with a breakpoint set at *0x0.
NeonLightions
Member
Member
Posts: 102
Joined: Wed Oct 20, 2021 6:00 pm
Location: Paraguay

Re: Jumping into infinite loop when mapping virtual address

Post by NeonLightions »

iansjack wrote:Well, that looks like you are trying to run the real mode interrupt vector table as code! Somehow your eip is being set to zero - probably as a result of stack corruption somewhere. Does a stack backtrack at the point of failure give you any clues? You could try running with a breakpoint set at *0x0.
No, I'm not using real mode interrupt vector as code. I have setup GDT and IDT correctly and nothing wrong with it, and I use GRUB as my bootloader so Protected Mode has already been enabled. I have backtrace with GDB and guess what? There's nothing in the stack, maybe the stack was corrupted?
davmac314
Member
Member
Posts: 121
Joined: Mon Jul 05, 2021 6:57 pm

Re: Jumping into infinite loop when mapping virtual address

Post by davmac314 »

NeonLightions wrote:No, I'm not using real mode interrupt vector as code. I have setup GDT and IDT correctly and nothing wrong with it, and I use GRUB as my bootloader so Protected Mode has already been enabled. I have backtrace with GDB and guess what? There's nothing in the stack, maybe the stack was corrupted?
I think that "using real mode interrupt vector table as code" was referring to the fact that the address executing appears to be 0x0 (or at least 0x1) which, if a physical address, is where the real mode interrupt vector table is located. From what you posted:
NeonLightions wrote:I have used QEMU to debug this issue, and the last instruction it did is:

Code: Select all

0x00000001:  ff 00                    incl     (%eax)
0x00000003:  f0                       .byte    0xf0
0x00000004:  53                       pushl    %ebx
0x00000005:  ff 00                    incl     (%eax)
0x00000007:  f0                       .byte    0xf0
0x00000008:  c3                       retl  
I think that is the address after mapped with paging.
Notice the instruction addresses, and it certainly looks like it could be the real mode IVT based on the byte values. The question then would be, how is execution managing to end up at this address? As suggested earlier, it's possible that you've got a stack corruption issue which is overwriting the return address within some function with a 0x0 (or 0x1) value. (Edit: removed sentence which couldn't be right.)
NeonLightions
Member
Member
Posts: 102
Joined: Wed Oct 20, 2021 6:00 pm
Location: Paraguay

Re: Jumping into infinite loop when mapping virtual address

Post by NeonLightions »

davmac314 wrote:
NeonLightions wrote:No, I'm not using real mode interrupt vector as code. I have setup GDT and IDT correctly and nothing wrong with it, and I use GRUB as my bootloader so Protected Mode has already been enabled. I have backtrace with GDB and guess what? There's nothing in the stack, maybe the stack was corrupted?
I think that "using real mode interrupt vector table as code" was referring to the fact that the address executing appears to be 0x0 (or at least 0x1) which, if a physical address, is where the real mode interrupt vector table is located. From what you posted:
NeonLightions wrote:I have used QEMU to debug this issue, and the last instruction it did is:

Code: Select all

0x00000001:  ff 00                    incl     (%eax)
0x00000003:  f0                       .byte    0xf0
0x00000004:  53                       pushl    %ebx
0x00000005:  ff 00                    incl     (%eax)
0x00000007:  f0                       .byte    0xf0
0x00000008:  c3                       retl  
I think that is the address after mapped with paging.
Notice the instruction addresses, and it certainly looks like it could be the real mode IVT based on the byte values. The question then would be, how is execution managing to end up at this address? As suggested earlier, it's possible that you've got a stack corruption issue which is overwriting the return address within some function with a 0x0 (or 0x1) value. (Edit: removed sentence which couldn't be right.)
Do you have any suggestion to fix this issue? (Edit: if you want source code, I can give you that)
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Jumping into infinite loop when mapping virtual address

Post by neon »

Hi,
/** Kernel heap starts above all ELF sections. */
kheap_curr = ADDR_PAGE_ROUND_UP((uint32_t) elf_shstrtab_end);
So...where is the stack located at in relation to this?
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
NeonLightions
Member
Member
Posts: 102
Joined: Wed Oct 20, 2021 6:00 pm
Location: Paraguay

Re: Jumping into infinite loop when mapping virtual address

Post by NeonLightions »

neon wrote:Hi,
/** Kernel heap starts above all ELF sections. */
kheap_curr = ADDR_PAGE_ROUND_UP((uint32_t) elf_shstrtab_end);
So...where is the stack located at in relation to this?
Oh, the stack is below elf_shstrtab_end like this:

Code: Select all

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000100000  00001000
       0000000000003253  0000000000000000  AX       0     0     16
  [ 2] .data             PROGBITS         0000000000104000  00005000
       00000000000001c0  0000000000000000  WA       0     0     32
  [ 3] .rodata           PROGBITS         0000000000105000  00006000
       0000000000000250  0000000000000000   A       0     0     8
  [ 4] .rodata.str1.1    PROGBITS         0000000000105250  00006250
       000000000000035f  0000000000000001 AMS       0     0     1
  [ 5] .rodata.str1.8    PROGBITS         00000000001055b0  000065b0
       00000000000004f5  0000000000000001 AMS       0     0     8
  [ 6] .eh_frame         PROGBITS         0000000000105aa8  00006aa8
       00000000000005a0  0000000000000000   A       0     0     8
  [ 7] .rodata.cst8      PROGBITS         0000000000106048  00007048
       0000000000000070  0000000000000008  AM       0     0     8
  [ 8] .bss              NOBITS           0000000000107000  000070b8
       0000000000007018  0000000000000000  WA       0     0     4096
  [ 9] .comment          PROGBITS         0000000000000000  000070b8
       0000000000000012  0000000000000001  MS       0     0     1
  [10] .symtab           SYMTAB           0000000000000000  000070d0
       00000000000008a0  0000000000000018          11    45     8
  [11] .strtab           STRTAB           0000000000000000  00007970
       000000000000040d  0000000000000000           0     0     1
  [12] .shstrtab         STRTAB           0000000000000000  00007d7d
       0000000000000072  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)
... so I'm sure that won't affect to the stack.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Jumping into infinite loop when mapping virtual address

Post by neon »

Hi,

That wasn't what was requested. You see, something is very clearly setting R/EIP to 0. This is typically due to RET at the result of an invalid or corrupt stack. If the issue is indeed in that loop, it would most probably be from the heap allocator addresses as that loop writes over them. This can also technically come from corrupting the code segment itself but that is less likely (although not impossible.)

So what I was asking for was what the actual addresses the heap allocator actually returns and the actual current in-memory location of R/ESP before it jumps to 0.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
NeonLightions
Member
Member
Posts: 102
Joined: Wed Oct 20, 2021 6:00 pm
Location: Paraguay

Re: Jumping into infinite loop when mapping virtual address

Post by NeonLightions »

neon wrote:Hi,

That wasn't what was requested. You see, something is very clearly setting R/EIP to 0. This is typically due to RET at the result of an invalid or corrupt stack. If the issue is indeed in that loop, it would most probably be from the heap allocator addresses as that loop writes over them. This can also technically come from corrupting the code segment itself but that is less likely (although not impossible.)

So what I was asking for was what the actual addresses the heap allocator actually returns and the actual current in-memory location of R/ESP before it jumps to 0.
The last address _kalloc_temp() return is: 0010A000
If you want, you can check this: https://pastebin.com/XQYDi4ke
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Jumping into infinite loop when mapping virtual address

Post by neon »

Hi,

Based on the data in the last response...what happens if you disable hardware interrupts (cli instruction) before any of this?
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
NeonLightions
Member
Member
Posts: 102
Joined: Wed Oct 20, 2021 6:00 pm
Location: Paraguay

Re: Jumping into infinite loop when mapping virtual address

Post by NeonLightions »

neon wrote:Hi,

Based on the data in the last response...what happens if you disable hardware interrupts (cli instruction) before any of this?
I have done that and it's useless.
davmac314
Member
Member
Posts: 121
Joined: Mon Jul 05, 2021 6:57 pm

Re: Jumping into infinite loop when mapping virtual address

Post by davmac314 »

NeonLightions wrote:Do you have any suggestion to fix this issue?
I would start by figuring out exactly at what happens exactly when the loop gets "stuck", by single-stepping instruction-at-a-time using a debugger.
NeonLightions wrote:Yes, I have single-steped the code and it is very.... normal. It doesn't do anything cause crash or something, it's just... getting stop right there and and do nothing more.
What is the last instruction that executes before it seems to stop? And what are the relevant register values at that point, i.e is it writing some particular location in memory? What is the value of the stack pointer register at that point?
NeonLightions wrote:
neon wrote:Hi,

Based on the data in the last response...what happens if you disable hardware interrupts (cli instruction) before any of this?
I have done that and it's useless.
Yet, the trace you pasted showed an interrupt being handled and that this is possible where execution jumped to address 0x0. Maybe disabling interrupts doesn't make your code work as intended, but it's almost certainly changing something. And it certainly looks like you need to have interrupts disabled.

Then, if you still have a problem, the key thing is - what is the last instruction within the loop that executes, and what are the register values at that point?
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Jumping into infinite loop when mapping virtual address

Post by neon »

Hi,

Code: Select all

0x0010363b:  89 10                    movl     %edx, (%eax)
0x0010363d:  81 fb 00 00 00 08        cmpl     $0x8000000, %ebx
0x00103643:  74 7e                    je       0x1036c3
 
Servicing hardware INT=0x20
----------------
IN: 
0x00000000:  53                       pushl    %ebx
0x00000001:  ff 00                    incl     (%eax)
0x00000003:  f0                       .byte    0xf0
Go ahead and post a similar output with what you did before. Keep hardware interrupts disabled. The code posted before triggered the timer irq right before so we want to keep that disabled. If hardware interrupts are disabled, you should be getting different output.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply