Page 2 of 3
Re: Jumping into infinite loop when mapping virtual address
Posted: Mon Nov 22, 2021 5:43 am
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.)
Re: Jumping into infinite loop when mapping virtual address
Posted: Mon Nov 22, 2021 6:25 am
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?
Re: Jumping into infinite loop when mapping virtual address
Posted: Mon Nov 22, 2021 6:36 am
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.
Re: Jumping into infinite loop when mapping virtual address
Posted: Mon Nov 22, 2021 7:39 am
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.
Re: Jumping into infinite loop when mapping virtual address
Posted: Mon Nov 22, 2021 5:44 pm
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?
Re: Jumping into infinite loop when mapping virtual address
Posted: Tue Nov 23, 2021 7:35 pm
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.)
Re: Jumping into infinite loop when mapping virtual address
Posted: Tue Nov 23, 2021 8:37 pm
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)
Re: Jumping into infinite loop when mapping virtual address
Posted: Tue Nov 23, 2021 9:56 pm
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?
Re: Jumping into infinite loop when mapping virtual address
Posted: Wed Nov 24, 2021 12:41 am
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.
Re: Jumping into infinite loop when mapping virtual address
Posted: Wed Nov 24, 2021 1:07 pm
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.
Re: Jumping into infinite loop when mapping virtual address
Posted: Wed Nov 24, 2021 5:55 pm
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
Re: Jumping into infinite loop when mapping virtual address
Posted: Wed Nov 24, 2021 6:15 pm
by neon
Hi,
Based on the data in the last response...what happens if you disable hardware interrupts (cli instruction) before any of this?
Re: Jumping into infinite loop when mapping virtual address
Posted: Wed Nov 24, 2021 6:34 pm
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.
Re: Jumping into infinite loop when mapping virtual address
Posted: Wed Nov 24, 2021 7:44 pm
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?
Re: Jumping into infinite loop when mapping virtual address
Posted: Wed Nov 24, 2021 9:02 pm
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.