Question
VSCode: RtosProxy error with big thread stack on ThreadX
During a debugging session, when `tx_thread_create` is called with a "big" stack size (1024*10 for example) and the "serverRtos" is enabled, the debugger is disconnected with an error: "Remote communication error. Target disconnected: No error."
Here the debug console logs (full log attached):
Spoiler
To client: {"seq":0,"type":"event","event":"output","body":{"category":"proxy","output":"RTOS proxy: Lost connection to GDB Server\r\n"}}
RTOS proxy: Lost connection to GDB Server
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"{\"label\":\"\",\"value\":[{\"label\":\"Driver\",\"value\":\"ThreadX\"},{\"label\":\"Kernel state\",\"value\":\"Not started\"}]}\n"}}
{"label":"","value":[{"label":"Driver","value":"ThreadX"},{"label":"Kernel state","value":"Not started"}]}
GDB result: 36 done
To client: {"seq":0,"type":"response","request_seq":25,"command":"cdt-gdb-tests/executeCommand","success":true,"body":{"status":"Ok","result":{},"console":["monitor rtos -m state\n","{\"label\":\"\",\"value\":[{\"label\":\"Driver\",\"value\":\"ThreadX\"},{\"label\":\"Kernel state\",\"value\":\"Not started\"}]}\n"]}}
To client: {"seq":0,"type":"event","event":"output","body":{"category":"proxy","output":"RTOS proxy: Proxy stopped.\r\n"}}
RTOS proxy: Proxy stopped.
GDB notify async: thread-exited,id="1",group-id="i1"
GDB notify async: thread-group-exited,id="i1"
GDB result: 37 error,msg="Remote communication error. Target disconnected: No error."
RTOS proxy: Lost connection to GDB Server
To client: {"seq":0,"type":"event","event":"output","body":{"category":"stdout","output":"{\"label\":\"\",\"value\":[{\"label\":\"Driver\",\"value\":\"ThreadX\"},{\"label\":\"Kernel state\",\"value\":\"Not started\"}]}\n"}}
{"label":"","value":[{"label":"Driver","value":"ThreadX"},{"label":"Kernel state","value":"Not started"}]}
GDB result: 36 done
To client: {"seq":0,"type":"response","request_seq":25,"command":"cdt-gdb-tests/executeCommand","success":true,"body":{"status":"Ok","result":{},"console":["monitor rtos -m state\n","{\"label\":\"\",\"value\":[{\"label\":\"Driver\",\"value\":\"ThreadX\"},{\"label\":\"Kernel state\",\"value\":\"Not started\"}]}\n"]}}
To client: {"seq":0,"type":"event","event":"output","body":{"category":"proxy","output":"RTOS proxy: Proxy stopped.\r\n"}}
RTOS proxy: Proxy stopped.
GDB notify async: thread-exited,id="1",group-id="i1"
GDB notify async: thread-group-exited,id="i1"
GDB result: 37 error,msg="Remote communication error. Target disconnected: No error."
And the very basic code used:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file app_threadx.c
* @author MCD Application Team
* @brief ThreadX applicative file
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "app_threadx.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
TX_THREAD tx_app_thread;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
VOID th_main(ULONG thread_input)
{
while (1)
{
tx_thread_sleep(1);
}
}
TX_THREAD p_thMain;
#define MAIN_THREAD_STACK_SIZE (1024*10)
CHAR thMain_stack[MAIN_THREAD_STACK_SIZE];
/* USER CODE END PFP */
/**
* @brief Application ThreadX Initialization.
* memory_ptr: memory pointer
* @retval int
*/
UINT App_ThreadX_Init(VOID *memory_ptr)
{
UINT ret = TX_SUCCESS;
TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;
/* USER CODE BEGIN App_ThreadX_MEM_POOL */
/* USER CODE END App_ThreadX_MEM_POOL */
CHAR *pointer;
/* Allocate the stack for tx app thread */
if (tx_byte_allocate(byte_pool, (VOID**) &pointer,
TX_APP_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS)
{
return TX_POOL_ERROR;
}
/* Create tx app thread. */
if (tx_thread_create(&tx_app_thread, "tx app thread", tx_app_thread_entry, 0, pointer,
TX_APP_STACK_SIZE, TX_APP_THREAD_PRIO, TX_APP_THREAD_PREEMPTION_THRESHOLD,
TX_APP_THREAD_TIME_SLICE, TX_APP_THREAD_AUTO_START) != TX_SUCCESS)
{
return TX_THREAD_ERROR;
}
/* USER CODE BEGIN App_ThreadX_Init */
tx_thread_create(&p_thMain, "Main Thread", th_main, 0, thMain_stack,
MAIN_THREAD_STACK_SIZE, TX_APP_THREAD_PRIO, TX_APP_THREAD_PREEMPTION_THRESHOLD,
TX_APP_THREAD_TIME_SLICE, TX_APP_THREAD_AUTO_START);
/* USER CODE END App_ThreadX_Init */
return ret;
}
/**
* @brief Function implementing the tx_app_thread_entry thread.
* thread_input: Hardcoded to 0.
* @retval None
*/
void tx_app_thread_entry(ULONG thread_input)
{
/* USER CODE BEGIN tx_app_thread_entry */
while (1)
{
tx_thread_sleep(100);
}
/* USER CODE END tx_app_thread_entry */
}
/**
* @brief Function that implements the kernel's initialization.
* None
* @retval None
*/
void MX_ThreadX_Init(void)
{
/* USER CODE BEGIN Before_Kernel_Start */
/* USER CODE END Before_Kernel_Start */
tx_kernel_enter();
/* USER CODE BEGIN Kernel_Start_Error */
/* USER CODE END Kernel_Start_Error */
}
/**
* @brief App_ThreadX_LowPower_Timer_Setup
* count : TX timer count
* @retval None
*/
void App_ThreadX_LowPower_Timer_Setup(ULONG count)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Timer_Setup */
/* USER CODE END App_ThreadX_LowPower_Timer_Setup */
}
/**
* @brief App_ThreadX_LowPower_Enter
* None
* @retval None
*/
void App_ThreadX_LowPower_Enter(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Enter */
/* USER CODE END App_ThreadX_LowPower_Enter */
}
/**
* @brief App_ThreadX_LowPower_Exit
* None
* @retval None
*/
void App_ThreadX_LowPower_Exit(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Exit */
/* USER CODE END App_ThreadX_LowPower_Exit */
}
/**
* @brief App_ThreadX_LowPower_Timer_Adjust
* None
* @retval Amount of time (in ticks)
*/
ULONG App_ThreadX_LowPower_Timer_Adjust(void)
{
/* USER CODE BEGIN App_ThreadX_LowPower_Timer_Adjust */
return 0;
/* USER CODE END App_ThreadX_LowPower_Timer_Adjust */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
