def main(argv): kgdb = 'kgdb' in argv[1:] nowait = 'nowait' in argv[1:] gfx = 'gfx' in argv[1:] or 'graphics' in argv[1:] configs = [] args = [] for arg in argv[1:]: if arg in ('kgdb', 'nowait', 'gfx', 'graphics'): continue # UPPERCASE= is treated as a config options, # lowercase= or MixedCased= becomes a kernel option stem = arg.split('=')[0] if stem == stem.upper(): configs.append(arg) else: args.append(arg) if not nowait: args.append('kgdbwait') kbuild.config(kgdb=True, extra_config=configs) kbuild.build() ktest.qemu(interactive=True, gdb=kgdb, gfx=gfx, append=' '.join(args), second_uart=kgdb)
def test_kgdb(): '''High-level kgdb smoke test. Tour a number of kgdb features to prove that basic functionality if working OK. ''' kbuild.config(kgdb=True) kbuild.build() qemu = ktest.qemu(second_uart=True, gdb=True, append='kgdbwait') console = qemu.console gdb = qemu.debug console.expect_boot(skip_late=True) console.expect('Waiting for connection from remote gdb...') gdb.connect_to_target() gdb.send('where\r') gdb.expect('kgdb_initial_breakpoint') gdb.expect(['init_kgdboc', 'configure_kgdboc']) gdb.expect_prompt() gdb.send('break do_sys_open\r') gdb.expect_prompt() gdb.send('continue\r') gdb.expect('hit Breakpoint') gdb.expect_prompt() gdb.send('info registers\r') # If the PC is not automatically shown symbolically in a # register dump then we must look it up explicitly. if kbuild.get_arch() in ('mips', ): gdb.expect_prompt() gdb.send('info symbol $pc\r') # On x86_64 the PC lookup for this is __x64_sys_open (and on mips # it can be sys_open so we don't expect the 'do_'! gdb.expect('sys_open') gdb.expect_prompt() gdb.send('info thread\r') gdb.expect('oom_reaper') gdb.expect_prompt() gdb.send('thread 10\r') gdb.expect_prompt() gdb.send('where\r') gdb.expect('kthread') gdb.expect(['ret_from_fork', 'ret_from_kernel_thread', 'riscv.*entry[.]S']) gdb.expect_prompt() gdb.send('delete 1\r') gdb.expect_prompt() gdb.send('continue\r') console.expect_busybox() qemu.close()
def kdb(build): qemu = ktest.qemu(append='kgdbwait') console = qemu.console qemu.console.expect_boot(skip_late=True) yield qemu qemu.close()
def kgdb(build): qemu = ktest.qemu(second_uart=True, gdb=True, append='kgdbwait') qemu.console.expect_boot(skip_late=True) qemu.console.expect('Waiting for connection from remote gdb...') qemu.debug.connect_to_target() yield qemu qemu.close()
def kdb(): kbuild.config(kgdb=True) kbuild.build() qemu = ktest.qemu() console = qemu.console console.expect_boot() console.expect_busybox() yield qemu qemu.close()
def kdb(): kbuild.config(kgdb=True) kbuild.build() qemu = ktest.qemu() console = qemu.console console.expect_boot() console.expect_busybox() # Now we have booted our expectations should be met quickly console.timeout = 5 yield qemu qemu.close()
def test_earlycon(): kbuild.config(kgdb=True) kbuild.build() # Handle platforms that cannot auto-configure the earlycon arch = kbuild.get_arch() if 'x86' == arch: earlycon = "earlycon=uart8250,io,0x3f8" elif 'arm' == arch: earlycon = "earlycon=pl011,0x1c090000" else: earlycon = "earlycon" qemu = ktest.qemu(append=f'{earlycon} kgdboc_earlycon kgdbwait') console = qemu.console def expect_and_page(c, needle): choices = [needle, 'more>'] choice = c.expect(choices) while choice == 1: c.send(' ') choice = c.expect(choices) print(choice) print(choices) print("Done") # This test is too low level to use the regular console helpers console.expect_kdb() console.sendline_kdb('bt') if 'x86' in kbuild.get_arch(): # x86 uses earlycon with arguments and supports very early # consoles, expect to break whilst parsing early parameters expect_and_page(console, 'parse_early_param') elif 'arm64' in kbuild.get_arch(): # Currently arm64 doesn't implement ARCH_HAS_EARLY_DEBUG # expect_and_page(console, 'console_init') pass expect_and_page(console, 'start_kernel') console.expect_kdb() console.sendline_kdb('go') # At this point kgdb has already fired up (on the earlycon). That # means the early boot messages have already passed by, hence we # need to set skip_early in the boot expectations. qemu.console.expect_boot(skip_early=True) qemu.console.expect_busybox() qemu.close()
def kernel(build): qemu = ktest.qemu(kdb=False) console = qemu.console console.expect_boot() console.expect_busybox() # Older kernels have no async progress display so for these # kernels we just set a very long timeout (which means failures # will take a long time to report too) if kbuild.get_version() < (4, 17): console.timeout *= 10 print('Kernel is below v4.17, extended timeout to {}'.format( console.timeout)) yield qemu qemu.close()
def kgdb(): kbuild.config(kgdb=True) kbuild.build() qemu = ktest.qemu(second_uart=True, gdb=True) # Wait for qemu to boot qemu.console.expect_boot() qemu.console.expect_busybox() # Ensure debugger it attached qemu.console.sysrq('g') qemu.debug.connect_to_target() qemu.debug.send('continue\r') qemu.console.send('\r') qemu.console.expect_prompt() yield qemu qemu.close()
def test_kgdbts_boot(): kbuild.config(kgdb=True) kbuild.build() # # From drivers/misc/kgdbts.c: # # When developing a new kgdb arch specific implementation # or using these tests for the purpose of regression # testing, several invocations are required. # # 1) Boot with the test suite enabled by using the kernel arguments # "kgdbts=V1F100 kgdbwait" # qemu = ktest.qemu(kdb=False, append='kgdbwait kgdbts=V1F100') console = qemu.console # We expect the test suite to start whilst initializing modules # so we must skip the late boot expectations. console.expect_boot(skip_late=True) # Older kernels have no async progress display so for these # kernels we just set a very long timeout (which means failures # will take a long time to report too) if kbuild.get_version() < (4, 17): console.timeout *= 5 print('Kernel is below v4.17, extended timeout to {}'.format( console.timeout)) console.expect('Registered I/O driver kgdbts') # Check that the self test starts to run. The failure detect # relies on all error paths calling WARN_ON(). choices = [ 'WARNING.*kgdbts[.]c.*[/r/n]', 'KGDB: BP remove failed', 'kgdbts:RUN' ] choice = console.expect(choices) assert choice > 1 # Ordering is difficult here since the Unregistered I/O... message # is aynschnronous. We solve that just by waiting for all of the # following strings to appear (in any order). choices += [ '##INVALID##', 'Unregistered I/O driver kgdbts', 'Freeing unused kernel.*memory', 'Starting.*log', 'OK', 'Welcome to Buildroot', 'buildroot login:'******'{console.match.group(0)}', still waiting for {choices[4:]}" ) # HACK: Ignore problems with hw_break (we allow kgdbts_V1 # to report them and would like to see the results # of the single step tests here) assert choice > 1 or 'hw_break' in console.match.group(0) if 'login:'******'root') # After logging in then the prompt becomes a # valid choice (before that it's too easy to # mis-match) choices[3] = '#' elif '#' in choices[choice]: # Cause a sys_fork (if there are less than 100 forks # during the boot sequence the self test we started at # boot will not complete) console.sendline('date') num_forks += 1 assert num_forks < 100 if choice >= 4: del choices[choice] console.expect_prompt() qemu.close()