Skip to content

Qiling.emu_stop() does not stop the emulator when gdb debugger is attached #1310

@bstee615

Description

@bstee615

Describe the bug
Thank you for your work on this useful framework.

When executing this sample code, Qiling waits for gdb to connect. I attached gdb using target remote 127.0.0.1:9999, then used the stepi command repeatedly until the executable reached the entry of foo. When I use stepi on the entry to foo, then my script's function print_asm calls ql.emu_stop(), which should stop the emulator, but the emulator does not stop - it remains on the same instruction. Because of this, if instead I use the step command to step to the next statement, then gdb hang in an infinite loop.

Sample Code
Qiling script:

from qiling import *
from qiling.const import QL_VERBOSE

def test_gdb(path, rootfs):
    ql = Qiling(path, rootfs, verbose=QL_VERBOSE.OFF)

    # Enable debugger to listen at localhost address, default port 9999
    ql.debugger = True

    ba = ql.loader.images[0].base

    foo_addr = int("0000000000001135", 16)  # start address of foo
    foo_len = int("0000000000000024", 16)  # length of foo

    def print_asm(ql, address, size):
        print("INSTRUCTION:", hex(address), size)
        if address == ba + foo_addr:
            print("REACHED TARGET INSTRUCTION", hex(ba+foo_addr), "END EMU")
            ql.emu_stop()

    ql.hook_code(print_asm, begin=ba + foo_addr, end=ba + foo_addr + foo_len)
    ql.run()

if __name__ == "__main__":
    test_gdb(["./test"], "/")

Log of qiling script output: test_gdb.log

Expected behavior
When the ql.emu_stop() line is executed, emulation will quit and gdb will detach.

Additional context
I ran this test case on the official Docker container qilingframework/qiling:latest with the latest code from the dev branch.

It should be possible to reproduce the bug with any executable by calling Qiling.emu_stop() during execution.
Here is the target program I used:

#include <stdio.h>

void foo(int a) {
    printf("Hello, world %d!\n", a);
}

int main(int argc, char **argv)
{
    int a = 10;
    foo(a);
    return a;
}

Compiled executable (unzip it first): test.zip

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions