3

I have a simple project which comes to be a very very simple kernel. I have some issues with the code and tried to debug it using GDB. Here's the first problem the code is not an executable to be started and debugged in the GDB.

After, I tried to debug via QEMU, but since I archived my codes into .iso to be able to run it on QEMU. When I tried to set breakpoint in the source file (e.g. main function of kernel.cpp) gdb said that

No symbol table is loaded. Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n])

After I say yes, run the program - no breakpoints met.

I tried to google, but only things I find references to "How to debug linux kernel with gdb and qemu" and I couldn't find a way to adapt these suggestions with the "kernel" I have.

Here is my code

kernel.cpp

void printf(const char *string)`
{
    volatile unsigned char *vmem = (volatile unsigned char *)0xb8000;
    vmem[0] = 0x2f;
    vmem[1] = 0x4b;
    vmem[2] = 0x2f;
    vmem[3] = 0x4f;
}

extern "C" void kernelMain()
{
    printf("Hello world");
    while(1);
}

loader.s

section .multiboot
header_start:
    dd 0xe85250d6
    dd 0
    dd header_end - header_start
    dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start))
    dw 0
    dw 0
    dd 8
header_end:

global start
global printf

extern kernelMain

section .text
bits 32
start:
    call kernelMain
    hlt

_loop:
    jmp _loop

linker.ld

ENTRY(start)
OUTPUT_FORMAT("elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)

SECTIONS {
    . = 1M;

    .boot :
    {
        *(.multiboot)
    }

    .text ALIGN(4k):
    {
        *(.text)
    }

    .bss :
    {
        *(.bss)
    }

    .data :
    {
        *(.data)
    }

    .rodata : 
    {
        *(.rodata)
    }

    /DISCARD/ :
    {
        *(.fini_array*)
        *(.note.*)
        *(.eh_frame*)
        *(.comment)
    }
}

and finally makefile

GXXPARAMS = -m64 -march=x86-64 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -g

objects = kernel.o loader.o 

.PHONY : all clean pack deploy target

target : clean all pack

all : os.bin

%.o : %.cpp
    gcc -c $(GXXPARAMS) -o $@ $<

%.o : %.s
    nasm -felf64 -o $@ $<

os.bin : $(objects)
    ld -n -T linker.ld -o $@ $^

clean :
    rm -fr *.o *.iso *.bin

pack : all
    cp os.bin iso_tmp/boot/
    grub-mkrescue -o os.iso iso_tmp/

deploy : pack
    qemu-system-x86_64 -cdrom os.iso

UPDATE

In a response to @Michael Petch's question in comments - here's the GDB invoking command line

gdb qemu-system-x86_64

after GDB started, I write

b kernel.cpp:main

then y then

r -cdrom os.iso
arsdever
  • 1,111
  • 1
  • 11
  • 32
  • _"failed to set breakpoints"_ is not a good problem description. Describe what exactly you have done and any error messages. – Jester Feb 03 '20 at 12:11
  • There is a debugger in which you can debug kernel applications named "KDBG" try that – vishal Feb 03 '20 at 12:16
  • 3
    Are you aware that you can't properly run 64-bit code while in 32-bit protected mode? Multiboot doesn't put you in 64-bit long mode. It takes you as far as 32-bit protected mode with a flat memory model. You have to code the switch into long mode yourself. There is info here: https://wiki.osdev.org/Setting_Up_Long_Mode . I'd expect the code that prints may not output what you want as a consequence. THis of course doesn't answer your actual question, but it is a heads up to you. – Michael Petch Feb 03 '20 at 12:16
  • As for debugging you give a lot of info but haven't actually mentioned how you launch QEMU and GDB to debug. What are the command line parameters you are using to do it? – Michael Petch Feb 03 '20 at 12:22
  • For attaching GDB, have you tried the instructions at https://wiki.osdev.org/How_Do_I_Use_A_Debugger_With_My_OS#Use_GDB_with_QEMU ? If you cannot get that to work please show what you tried so we can spot errors. – Botje Feb 03 '20 at 12:31
  • FYI, you might want to use BOCHS instead of QEMU. I've heard BOCHS's built-in debugger is good for early-boot debugging because it understands x86 modes and segmentation, and has helpers for decoding GDT / LDT. – Peter Cordes Feb 03 '20 at 12:37
  • @vishal: `kdbg` is a KDE front-end for regular GDB. kgdb is the *Linux* kernel's built-in debugger. Neither of those are any help; kgdb only exists if the kernel implements debugging hooks. The OP is using QEMU's GDB-remote support to attach to the virtual machine running the kernel; that doesn't require the kernel itself to know anything about it or have a debugger built-in. – Peter Cordes Feb 03 '20 at 12:39
  • @MichaelPetch can you please check the updated question? – arsdever Feb 03 '20 at 13:04
  • You're debugging QEMU itself, not the guest machine it's emulating. Google how to attach to QEMU as a GDB remote. – Peter Cordes Feb 03 '20 at 13:05
  • @PeterCordes I understand, but thought that while the QEMU uses my generated binaries maybe I will be able to debug them. – arsdever Feb 03 '20 at 13:06
  • @Botje Thanks for your link. It helped me. I was able to enter into debug mode. – arsdever Feb 03 '20 at 13:19

0 Answers0