mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
test: gdbstub_runtime: initial commit
This commit is contained in:
parent
96768d7596
commit
9220eea4e4
@ -130,6 +130,12 @@ tools/test_apps/system/gdb_loadable_elf:
|
||||
temporary: true
|
||||
reason: target esp32c6, esp32h2 is not supported yet
|
||||
|
||||
tools/test_apps/system/gdbstub_runtime:
|
||||
disable_test:
|
||||
- if: IDF_TARGET in ["esp32c2", "esp32h2"]
|
||||
temporary: true
|
||||
reason: resolve IDF-7264
|
||||
|
||||
tools/test_apps/system/longjmp_test:
|
||||
enable:
|
||||
- if: IDF_TARGET in ["esp32", "esp32s2", "esp32s3"]
|
||||
|
8
tools/test_apps/system/gdbstub_runtime/CMakeLists.txt
Normal file
8
tools/test_apps/system/gdbstub_runtime/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(COMPONENTS main)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(test_gdbstub_runtime)
|
2
tools/test_apps/system/gdbstub_runtime/README.md
Normal file
2
tools/test_apps/system/gdbstub_runtime/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
|
26
tools/test_apps/system/gdbstub_runtime/conftest.py
Normal file
26
tools/test_apps/system/gdbstub_runtime/conftest.py
Normal file
@ -0,0 +1,26 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# pylint: disable=W0621 # redefined-outer-name
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
from _pytest.fixtures import FixtureRequest
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
|
||||
sys.path.append(os.path.expandvars(os.path.join('$IDF_PATH', 'tools', 'test_apps', 'system', 'panic')))
|
||||
from test_panic_util import PanicTestDut # noqa: E402
|
||||
|
||||
|
||||
@pytest.fixture(scope='module')
|
||||
def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch:
|
||||
mp = MonkeyPatch()
|
||||
request.addfinalizer(mp.undo)
|
||||
return mp
|
||||
|
||||
|
||||
@pytest.fixture(scope='module', autouse=True)
|
||||
def replace_dut_class(monkeypatch_module: MonkeyPatch) -> None:
|
||||
monkeypatch_module.setattr('pytest_embedded_idf.IdfDut', PanicTestDut)
|
@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "test_app_main.c"
|
||||
INCLUDE_DIRS ""
|
||||
REQUIRES esp_gdbstub)
|
26
tools/test_apps/system/gdbstub_runtime/main/test_app_main.c
Normal file
26
tools/test_apps/system/gdbstub_runtime/main/test_app_main.c
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int var_1;
|
||||
int var_2;
|
||||
|
||||
void foo(void)
|
||||
{
|
||||
var_2++;
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
printf("tested app is runnig.\n");
|
||||
while(1) {
|
||||
var_1++;
|
||||
if (var_1 % 10 == 0) {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
}
|
114
tools/test_apps/system/gdbstub_runtime/pytest_runtime.py
Normal file
114
tools/test_apps/system/gdbstub_runtime/pytest_runtime.py
Normal file
@ -0,0 +1,114 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.append(os.path.expandvars(os.path.join('$IDF_PATH', 'tools', 'test_apps', 'system', 'panic')))
|
||||
from test_panic_util import PanicTestDut # noqa: E402
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32c2', 'esp32h2'], reason='resolve IDF-7264')
|
||||
@pytest.mark.generic
|
||||
def test_gdbstub_runtime(dut: PanicTestDut) -> None:
|
||||
dut.expect_exact('tested app is runnig.')
|
||||
dut.write(b'\x03') # send Ctrl-C
|
||||
dut.start_gdb()
|
||||
|
||||
# Test breakpoint
|
||||
cmd = '-break-insert --source test_app_main.c --line 23'
|
||||
response = dut.find_gdb_response('done', 'result', dut.gdb_write(cmd))
|
||||
assert response is not None
|
||||
cmd = '-exec-continue'
|
||||
responses = dut.gdb_write(cmd)
|
||||
assert dut.find_gdb_response('running', 'result', responses) is not None
|
||||
if not dut.find_gdb_response('stopped', 'notify', responses):
|
||||
# does not stoped on breakpoint yet
|
||||
responses = dut.gdbmi.get_gdb_response(timeout_sec=3)
|
||||
assert dut.find_gdb_response('stopped', 'notify', responses) is not None
|
||||
payload = dut.find_gdb_response('stopped', 'notify', responses)['payload']
|
||||
assert payload['reason'] == 'breakpoint-hit'
|
||||
assert payload['bkptno'] == '1'
|
||||
assert payload['frame']['func'] == 'app_main'
|
||||
assert payload['frame']['line'] == '23'
|
||||
assert payload['stopped-threads'] == 'all'
|
||||
|
||||
# Test step command
|
||||
cmd = '-exec-step'
|
||||
responses = dut.gdb_write(cmd)
|
||||
assert dut.find_gdb_response('running', 'result', responses) is not None
|
||||
if not dut.find_gdb_response('stopped', 'notify', responses):
|
||||
# does not stoped on breakpoint yet
|
||||
responses = dut.gdbmi.get_gdb_response(timeout_sec=3)
|
||||
assert dut.find_gdb_response('stopped', 'notify', responses) is not None
|
||||
payload = dut.find_gdb_response('stopped', 'notify', responses)['payload']
|
||||
assert payload['reason'] == 'end-stepping-range'
|
||||
assert payload['frame']['func'] == 'foo'
|
||||
assert payload['frame']['line'] == '14'
|
||||
assert payload['stopped-threads'] == 'all'
|
||||
|
||||
# Test finish command
|
||||
cmd = '-exec-finish'
|
||||
responses = dut.gdb_write(cmd)
|
||||
assert dut.find_gdb_response('running', 'result', responses) is not None
|
||||
if not dut.find_gdb_response('stopped', 'notify', responses):
|
||||
# does not stoped on breakpoint yet
|
||||
responses = dut.gdbmi.get_gdb_response(timeout_sec=3)
|
||||
assert dut.find_gdb_response('stopped', 'notify', responses) is not None
|
||||
payload = dut.find_gdb_response('stopped', 'notify', responses)['payload']
|
||||
assert payload['reason'] == 'function-finished'
|
||||
assert payload['frame']['line'] == '23'
|
||||
assert payload['frame']['func'] == 'app_main'
|
||||
assert payload['stopped-threads'] == 'all'
|
||||
|
||||
# Test next command
|
||||
cmd = '-exec-next'
|
||||
responses = dut.gdb_write(cmd)
|
||||
assert dut.find_gdb_response('running', 'result', responses) is not None
|
||||
if not dut.find_gdb_response('stopped', 'notify', responses):
|
||||
# does not stoped on breakpoint yet
|
||||
responses = dut.gdbmi.get_gdb_response(timeout_sec=3)
|
||||
assert dut.find_gdb_response('stopped', 'notify', responses) is not None
|
||||
payload = dut.find_gdb_response('stopped', 'notify', responses)['payload']
|
||||
assert payload['reason'] == 'end-stepping-range'
|
||||
assert payload['frame']['line'] == '21'
|
||||
assert payload['frame']['func'] == 'app_main'
|
||||
assert payload['stopped-threads'] == 'all'
|
||||
|
||||
# test delete breakpoint
|
||||
cmd = '-break-delete 1'
|
||||
responses = dut.gdb_write(cmd)
|
||||
assert dut.find_gdb_response('done', 'result', responses) is not None
|
||||
cmd = '-exec-continue'
|
||||
responses = dut.gdb_write(cmd)
|
||||
assert dut.find_gdb_response('running', 'result', responses) is not None
|
||||
assert dut.find_gdb_response('running', 'notify', responses) is not None
|
||||
|
||||
# test ctrl-c
|
||||
responses = dut.gdbmi.send_signal_to_gdb(2)
|
||||
# assert dut.find_gdb_response('stopped', 'notify', responses) is not None
|
||||
# ?? No response? check we stopped
|
||||
dut.gdb_backtrace()
|
||||
|
||||
# test watchpoint
|
||||
cmd = '-break-watch var_2'
|
||||
responses = dut.gdb_write(cmd)
|
||||
assert dut.find_gdb_response('done', 'result', responses) is not None
|
||||
cmd = '-exec-continue'
|
||||
responses = dut.gdb_write(cmd)
|
||||
assert dut.find_gdb_response('running', 'result', responses) is not None
|
||||
if not dut.find_gdb_response('stopped', 'notify', responses):
|
||||
# does not stoped on breakpoint yet
|
||||
responses = dut.gdbmi.get_gdb_response(timeout_sec=3)
|
||||
payload = dut.find_gdb_response('stopped', 'notify', responses)['payload']
|
||||
assert payload['reason'] == 'signal-received'
|
||||
assert payload['frame']['func'] == 'foo'
|
||||
assert payload['stopped-threads'] == 'all'
|
||||
# Uncomment this when implement send reason to gdb: GCC-313
|
||||
#
|
||||
# assert payload['reason'] == 'watchpoint-trigger'
|
||||
# assert int(payload['value']['new']) == int(payload['value']['old']) + 1
|
||||
# assert payload['frame']['line'] == '14'
|
@ -0,0 +1,2 @@
|
||||
CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME=y
|
||||
CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y
|
Loading…
x
Reference in New Issue
Block a user