User:TheCool1Kevin/VSCode Debug: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
Content added Content deleted
No edit summary
No edit summary
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Rating|1|}}

== Preparing your Project ==
== Preparing your Project ==


Line 12: Line 14:


Your empty <code>launch.json</code> should look like:
Your empty <code>launch.json</code> should look like:
<source lang="javascript">
<syntaxhighlight lang="javascript">
{
{
"version": "0.2.0",
"version": "0.2.0",
"configurations": []
"configurations": []
}
}
</syntaxhighlight>
</source>


Inside <code>"configurations"</code>, create a new entry:
Inside <code>"configurations"</code>, create a new entry:


<source lang="javascript">
<syntaxhighlight lang="javascript">
{
{
"name": "Launch with GDB",
"name": "Launch with GDB",
Line 51: Line 53:
"preLaunchTask": "Launch QEMU"
"preLaunchTask": "Launch QEMU"
}
}
</syntaxhighlight>
</source>


And configure it based on your project:
And configure it based on your project:
Line 89: Line 91:


Under <code>setupCommands</code> add:
Under <code>setupCommands</code> add:
<source lang="javascript">
<syntaxhighlight lang="javascript">
{
{
"text": "file C:/Users/USER/PATH/TO/BINARY/myos.bin",
"text": "file C:/Users/USER/PATH/TO/BINARY/myos.bin",
Line 98: Line 100:
"description": "Break on exception handler."
"description": "Break on exception handler."
}
}
</syntaxhighlight>
</source>


The first command loads the binary file into GDB. Make sure that, regardless of your host OS, you include the full path to your OS binary (issue [https://github.com/Microsoft/vscode-cpptools/issues/815 #815].
The first command loads the binary file into GDB. Make sure that, regardless of your host OS, you include the full path to your OS binary (issue [https://github.com/Microsoft/vscode-cpptools/issues/815 #815].
Line 106: Line 108:


Your empty <code>tasks.json</code> should look like:
Your empty <code>tasks.json</code> should look like:
<source lang="javascript">
<syntaxhighlight lang="javascript">
{
{
"version": "2.0.0",
"version": "2.0.0",
"tasks": []
"tasks": []
}
}
</syntaxhighlight>
</source>


Under <code>"tasks"</code>, create a new entry:
Under <code>"tasks"</code>, create a new entry:
<source lang="javascript">
<syntaxhighlight lang="javascript">
{
{
"label": "Launch QEMU",
"label": "Launch QEMU",
Line 125: Line 127:
}
}
}
}
</syntaxhighlight>
</source>


'''Note that I have not tried the Linux command.''' It is important that QEMU is started in the background, so the command is executed asynchronously.
'''Note that I have not tried the Linux command.''' It is important that QEMU is started in the background, so the command is executed asynchronously.
Line 134: Line 136:
== Debugging ==
== Debugging ==


VSCode is not set up to debug normally. Press <code>F5</code> (or <code>FN+F5</code>) to debug!
VSCode is not set up to debug normally. Press <code>F5</code> (or <code>FN+F5</code>) to debug.
The IDE provides a nice graphical wrapper to GDB and an easy way to start the debugger from within the IDE. All features supported with GDB is supported with VSCode.

Some things you can do from within the debug console:
* <code>-exec</code> executes a GDB command, i.e., <code>-exec info registers</code> executes the command <code>info registers</code>
* You can evaluate expressions with graphical display of the data, for example:
** <code>(struct myStruct *) 0xCAFEBABE</code> will display the memory contents casted to the struct (there's a nice GUI tree view).
** <code>myVariable</code> will print out the value of that vaariable.
** <code>myStruct -> member</code> works too
** <code>*(myPointer + 2)</code> works
** Basically anything short of evaluating functions works.

If you have any issues, let me know (somehow)!
If you have any issues, let me know (somehow)!


== Screenshot ==
== Screenshots ==


See local variables, stack trace and all that good stuff.
See local variables, stack trace and all that good stuff.
Line 143: Line 156:
[[File:Vscode_debug.PNG|700px||VSCode Debug]]
[[File:Vscode_debug.PNG|700px||VSCode Debug]]


<br />
By typing <code>-exec info registers</code> into the debug console, you are able to see all the registers.
By typing <code>-exec info registers</code> into the debug console, you are able to see all the registers.


[[File:Vscode_dbg1.PNG|700px||VSCode Debug]]
[[File:Vscode_dbg1.PNG|600px||VSCode Debug]]

<br />
Exception catching works!

[[File:Vscode_dbg2.PNG|700px||VSCode Debug]]

[[:Category:OS Development]]
[[:Category:Tutorials]]
[[:Category:Tools]]
[[:Category:IDEs]]
[[Category:User drafts]]

Latest revision as of 20:11, 16 June 2024

Difficulty level

Beginner

Preparing your Project

If your project is already set up with VSCode, you may want to skip this section. First, you'll need to install VSCode and configure your project with VSCode. To do that, grab a copy of VSCode from the official website (fortunately, it is cross-platform). For this tutorial, you will need to have configured and installed the C/C++ extension by Microsoft. To install extensions, follow this guide: VS Code Extension Marketplace. Furthermore, you may also want to configure Intellisense for your project by following this guide: C/C++ for VS Code. Finally, familiarize yourself with the VSCode configuration files, namely:

  • .vscode/tasks.json
  • .vscode/launch.json

If a file listed above does not exist, you will have to manually create it.

Setting up launch.json

Your empty launch.json should look like:

{
    "version": "0.2.0",
    "configurations": []
}

Inside "configurations", create a new entry:

{
    "name": "Launch with GDB",
    "type": "cppdbg",
    "request": "launch",
    "program": "",
    "cwd": "",
    "args": [],
    "sourceFileMap": {
        "<source-path>": "<target-path>"
    },
    "targetArchitecture": "",
    "MIMode": "gdb",
    "miDebuggerPath": "",
    "miDebuggerArgs": "",
    "customLaunchSetupCommands": [
        {
            "text": "target remote localhost:1234",
            "description": "Connect to QEMU remote debugger"
        }
    ],
    "setupCommands": [
        {
            "description": "Enable pretty-printing for gdb",
            "text": "-enable-pretty-printing",
            "ignoreFailures": true
        }
    ],
    "preLaunchTask": "Launch QEMU"
}

And configure it based on your project:

Option name Description
program The program binary, it doesn't really matter what you set it to. I set it to ${workspaceRoot}/bin/myos.bin
cwd The current working directory. It really doesn't matter actually due to some issues with VSCode. I set it to ${workspaceRoot}
sourceFileMap This will replace the first instance of <source-path> with <target-path>.

I set <source-path> to /mnt/c/ and <target-path> to /C:/. This was supposed to fix this error I was getting:

Unable to open 'exceptions.c':
File not found (file:///mnt/c/Users/USER/PATH/TO/FILE/file.c).

If you're not having this issue, you should remove this option entirely.

targetArchitecture Self explanatory. I set it to x86
miDebuggerPath The path to your gdb executable. I set it to C:/cygwin64/bin/gdb.exe. You may want to set it to /usr/bin/gdb.
setupCommands Explained below. A bunch of GDB commands to be run in sequential order.
preLaunchTask A task to be run before GDB is launched.

Under setupCommands add:

{
    "text": "file C:/Users/USER/PATH/TO/BINARY/myos.bin",
    "description": "Load binary."
},
{
    "text": "break isr_handler",
    "description": "Break on exception handler."
}

The first command loads the binary file into GDB. Make sure that, regardless of your host OS, you include the full path to your OS binary (issue #815. The second command is optional. It's to catch exceptions.

Setting up tasks.json

Your empty tasks.json should look like:

{
    "version": "2.0.0",
    "tasks": []
}

Under "tasks", create a new entry:

{
    "label": "Launch QEMU",
    "type": "shell",
    "windows": {
        "command": "start -FilePath 'qemu-system-i386' -ArgumentList '-S -gdb tcp::1234 -boot d -cdrom bin/myos.iso -m 512'"
    }
    "linux": {
        "command": "qemu -S -gdb tcp::1234 -boot d -cdrom bin/myos.iso -m 512 &"
    }
}

Note that I have not tried the Linux command. It is important that QEMU is started in the background, so the command is executed asynchronously. Notice that VSCode for Windows executes Powershell which makes it a pain in the ass to start a process asynchronously.

Also, note that the value under label corresponds to the value under preLaunchTask as we are launching QEMU before GDB starts.

Debugging

VSCode is not set up to debug normally. Press F5 (or FN+F5) to debug. The IDE provides a nice graphical wrapper to GDB and an easy way to start the debugger from within the IDE. All features supported with GDB is supported with VSCode.

Some things you can do from within the debug console:

  • -exec executes a GDB command, i.e., -exec info registers executes the command info registers
  • You can evaluate expressions with graphical display of the data, for example:
    • (struct myStruct *) 0xCAFEBABE will display the memory contents casted to the struct (there's a nice GUI tree view).
    • myVariable will print out the value of that vaariable.
    • myStruct -> member works too
    • *(myPointer + 2) works
    • Basically anything short of evaluating functions works.

If you have any issues, let me know (somehow)!

Screenshots

See local variables, stack trace and all that good stuff.

VSCode Debug


By typing -exec info registers into the debug console, you are able to see all the registers.

VSCode Debug


Exception catching works!

VSCode Debug

Category:OS Development Category:Tutorials Category:Tools Category:IDEs