Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support GDB stub for remote debugging #74

Merged
merged 1 commit into from
Feb 10, 2025
Merged

Conversation

RinHizakura
Copy link
Contributor

@RinHizakura RinHizakura commented Feb 6, 2025

Enable the emulator to act as gdbstub. This feature helps to dignose and debug issue of emulator more simply.

Summary by Bito

This PR implements GDB remote debugging functionality by integrating mini-gdbstub library, adding debug mode with -g option, and restructuring the main emulation loop. The changes enable the emulator to function as a GDB remote target on port 1234, supporting interactive debugging through register/memory access and execution control features.

Unit tests added: False

Estimated effort to review (1-5, lower is better): 4

Copy link

bito-code-review bot commented Feb 6, 2025

Code Review Agent Run #c506b3

Actionable Suggestions - 5
Review Details
  • Files reviewed - 5 · Commit Range: f592ae8..f592ae8
    • .gitmodules
    • Makefile
    • device.h
    • main.c
    • mini-gdbstub
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Fb Infer (Static Code Analysis) - ✖︎ Failed

AI Code Review powered by Bito Logo

Copy link

bito-code-review bot commented Feb 6, 2025

Changelist by Bito

This pull request implements the following key changes.

Key Change Files Impacted
New Feature - GDB Remote Debugging Support

.gitmodules - Added mini-gdbstub submodule for GDB protocol support

Makefile - Added build configuration for mini-gdbstub integration

device.h - Added debug mode and interrupt handling fields to emulator state

main.c - Implemented GDB stub functionality and debug mode support

Comment on lines +683 to +684
emu->mtimer.mtimecmp = calloc(vm->n_hart, sizeof(uint64_t));
emu->mswi.msip = calloc(vm->n_hart, sizeof(uint32_t));
emu->sswi.ssip = calloc(vm->n_hart, sizeof(uint32_t));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider checking calloc return values

Consider checking if memory allocation for mtimecmp, msip, and ssip arrays was successful to handle out-of-memory conditions gracefully.

Code suggestion
Check the AI-generated fix before applying
Suggested change
emu->mtimer.mtimecmp = calloc(vm->n_hart, sizeof(uint64_t));
emu->mswi.msip = calloc(vm->n_hart, sizeof(uint32_t));
emu->sswi.ssip = calloc(vm->n_hart, sizeof(uint32_t));
emu->mtimer.mtimecmp = calloc(vm->n_hart, sizeof(uint64_t));
if (!emu->mtimer.mtimecmp) {
fprintf(stderr, "Failed to allocate mtimecmp array\n");
return -1;
}
emu->mswi.msip = calloc(vm->n_hart, sizeof(uint32_t));
if (!emu->mswi.msip) {
fprintf(stderr, "Failed to allocate msip array\n");
return -1;
}
emu->sswi.ssip = calloc(vm->n_hart, sizeof(uint32_t));
if (!emu->sswi.ssip) {
fprintf(stderr, "Failed to allocate ssip array\n");
return -1;
}

Code Review Run #c506b3


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged

virtio_net_refresh_queue(&emu->vnet);
if (emu->vnet.InterruptStatus)
emu_update_vnet_interrupts(vm);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing feature guard for VIRTIONET access

The code is accessing vnet member without checking if VIRTIONET is enabled. Consider adding proper #ifdef guards.

Code suggestion
Check the AI-generated fix before applying
Suggested change
virtio_net_refresh_queue(&emu->vnet);
if (emu->vnet.InterruptStatus)
emu_update_vnet_interrupts(vm);
#if SEMU_HAS(VIRTIONET)
virtio_net_refresh_queue(&emu->vnet);
if (emu->vnet.InterruptStatus)
emu_update_vnet_interrupts(vm);
#endif

Code Review Run #c506b3


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged

Comment on lines +749 to +748
vm_error_report(vm->hart[i]);
return 2;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider enhancing error reporting details

Consider adding more detailed error reporting. The current vm_error_report() call could be enhanced with additional context about which hart failed and what operation was being performed.

Code suggestion
Check the AI-generated fix before applying
Suggested change
vm_error_report(vm->hart[i]);
return 2;
fprintf(stderr, "Error in hart %d: ", i);
vm_error_report(vm->hart[i]);
return 2;

Code Review Run #c506b3


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged

Comment on lines +782 to +779
if (regno > 32)
return EFAULT;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signed vs unsigned comparison issue

The regno parameter in semu_read_reg() is compared against 32 but the function accepts it as signed int. Consider using unsigned comparison to prevent potential issues with negative values.

Code suggestion
Check the AI-generated fix before applying
Suggested change
if (regno > 32)
return EFAULT;
if (regno < 0 || regno > 32)
return EFAULT;

Code Review Run #c506b3


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged

main.c Outdated
Comment on lines 796 to 797
{
semu_t *semu = (semu_t *) args;
hart_t *hart = semu->vm.hart[semu->curr_cpuid];
mem_load(hart, addr, len, val);
return 0;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error handling for mem_load call

Consider adding error handling for mem_load() call in semu_read_mem(). The function may fail but the error is not propagated to the caller.

Code suggestion
Check the AI-generated fix before applying
Suggested change
{
semu_t *semu = (semu_t *) args;
hart_t *hart = semu->vm.hart[semu->curr_cpuid];
mem_load(hart, addr, len, val);
return 0;
}
{
semu_t *semu = (semu_t *) args;
hart_t *hart = semu->vm.hart[semu->curr_cpuid];
mem_load(hart, addr, len, val);
if (hart->error) {
hart->error = ERR_NONE;
return EFAULT;
}
return 0;
}

Code Review Run #c506b3


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged


/* Initialize the emulator */
emu_state_t emu;
memset(&emu, 0, sizeof(emu));
memset(emu, 0, sizeof(*emu));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the comments in riscv.h carefully:

/* To use the emulator, start by initializing a hart_t object with zero values,
 * invoke vm_init(), and set the required environment-supplied callbacks. You
 * may also set other necessary fields such as argument registers and s_mode,
 * ensuring that all field restrictions are met to avoid undefined behavior.
 *
 * Once the emulator is set up, execute the emulation loop by calling
 * "vm_step()" repeatedly. Each call attempts to execute a single instruction.
 *
 * If the execution completes successfully, the "vm->error" field will be set
 * to ERR_NONE. However, if an error occurs during execution, the emulator will
 * halt and the "vm->error" field will provide information about the error. It
 * is important to handle the emulation error before calling "vm_step()" again;
 * otherwise, it will not execute any instructions. The possible errors are
 * described above for reference.
 */

Do follow the manner unless you are about to refine the usage as the major purpose.

Copy link
Contributor Author

@RinHizakura RinHizakura Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of abstracting semu_init() here is to share the same logic between debug & normal mode. The behavior in normal mode should not be changed here. We follow these APIs in the same way.

@RinHizakura
Copy link
Contributor Author

RinHizakura commented Feb 7, 2025

I think the change still respects the riscv.h manner, as no behavior changes for the normal mode. Also, I don't want to fix the reviews by BOT here since they just follow the original implementation. The commit just separates the initialization of semu to reuse it for debug mode. Please let me know if you still need any changes from me.

@RinHizakura RinHizakura requested a review from jserv February 7, 2025 14:05
main.c Outdated
{
char *kernel_file;
char *dtb_file;
char *initrd_file;
char *disk_file;
char *netdev;
int hart_count = 1;
bool debug = false;
emu_state_t *emu = &semu->emu;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The statement emu_state_t *emu = &semu->emu; does not look elegant since adjacent semu and emu cause confusion. Can you refine it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name semu for semu_t is very intuitive, and I don't want to change emu to other names as it used to define like. The solution I can come up with here is to change semu_t to other names. Any suggestion?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about consolidating the existing semu structure instead?

.gitmodules Outdated Show resolved Hide resolved
Copy link

bito-code-review bot commented Feb 8, 2025

Code Review Agent Run #fb547c

Actionable Suggestions - 2
  • main.c - 2
Review Details
  • Files reviewed - 5 · Commit Range: 0a1d601..0a1d601
    • .gitmodules
    • Makefile
    • device.h
    • main.c
    • mini-gdbstub
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Fb Infer (Static Code Analysis) - ✖︎ Failed

AI Code Review powered by Bito Logo

vm_step(vm->hart[i]);
if (likely(!vm->hart[i]->error))
continue;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider reordering vm_step error check

Consider moving the error check for vm_step() before updating timer and SWI interrupts. If vm_step() fails, the interrupt state may be inconsistent.

Code suggestion
Check the AI-generated fix before applying
 -        emu_update_timer_interrupt(vm->hart[i]);
 -        emu_update_swi_interrupt(vm->hart[i]);
 -
 -        vm_step(vm->hart[i]);
 -        if (likely(!vm->hart[i]->error))
 -            continue;
 +        vm_step(vm->hart[i]);
 +        if (likely(!vm->hart[i]->error)) {
 +            emu_update_timer_interrupt(vm->hart[i]);
 +            emu_update_swi_interrupt(vm->hart[i]);
 +            continue;
 +        }

Code Review Run #fb547c


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged

vm_step(vm->hart[i]);
if (likely(!vm->hart[i]->error))
continue;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding vm_step error handling

Consider adding error handling for vm_step() return value. The function may return an error state that should be handled before continuing execution.

Code suggestion
Check the AI-generated fix before applying
Suggested change
vm_step(vm->hart[i]);
if (likely(!vm->hart[i]->error))
continue;
int step_ret = vm_step(vm->hart[i]);
if (step_ret != 0)
return step_ret;
if (likely(!vm->hart[i]->error))
continue;

Code Review Run #fb547c


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged

@RinHizakura RinHizakura requested a review from jserv February 9, 2025 12:38
@jserv jserv changed the title Support debug mode as gdbstub for semu Support GDB stub for remote debugging Feb 9, 2025
Copy link

bito-code-review bot commented Feb 10, 2025

Code Review Agent Run #8e516e

Actionable Suggestions - 1
  • device.h - 1
    • Consider initializing debug flag default value · Line 358-358
Additional Suggestions - 2
  • Makefile - 1
    • Consider adding error handling for make clean · Line 163-163
  • device.h - 1
Review Details
  • Files reviewed - 5 · Commit Range: 2dc7cf7..2dc7cf7
    • .gitmodules
    • Makefile
    • device.h
    • main.c
    • mini-gdbstub
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Fb Infer (Static Code Analysis) - ✖︎ Failed

AI Code Review powered by Bito Logo

@RinHizakura
Copy link
Contributor Author

Integrate all fields include vm_t into emu_state_t, means to use emu_state_t to represent the main body of semu

@@ -355,9 +355,11 @@ bool virtio_snd_init(virtio_snd_state_t *vsnd);

/* memory mapping */
typedef struct {
bool debug;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider initializing debug flag default value

Consider initializing the debug flag to a default value since it's a boolean field in the emu_state_t struct. This helps prevent undefined behavior if the field is accessed before being explicitly set.

Code suggestion
Check the AI-generated fix before applying
Suggested change
bool debug;
bool debug = false;

Code Review Run #8e516e


Is this a valid issue, or was it incorrectly flagged by the Agent?

  • it was incorrectly flagged

Enable the emulator to act as gdbstub. This feature helps
to dignose and debug issue of emulator more simply.
Copy link

bito-code-review bot commented Feb 10, 2025

Code Review Agent Run #73b0fa

Actionable Suggestions - 0
Additional Suggestions - 1
  • Makefile - 1
    • Consider adding error handling for make clean · Line 163-163
Review Details
  • Files reviewed - 5 · Commit Range: ae260eb..ae260eb
    • .gitmodules
    • Makefile
    • device.h
    • main.c
    • mini-gdbstub
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Fb Infer (Static Code Analysis) - ✖︎ Failed

AI Code Review powered by Bito Logo

@jserv jserv merged commit 2a521f6 into sysprog21:master Feb 10, 2025
3 checks passed
@jserv
Copy link
Collaborator

jserv commented Feb 10, 2025

Thank @RinHizakura for contributing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants