nuttx-apps/testing/nxdiag/nxdiag.c
Lucas Saavedra Vaz eb36c15171 testing: Add application to gather debug information (nxdiag)
This commit aims to add an application to gather debug information about the host and target systems. It can also perform some diagnostic checks on the host and target systems.
This will facilitate the process of users seeking assistance for solving some problem.

Current capabilities:
- Get host OS version;
- Get host python modules;
- Get host system packages;
- Get host PATH;
- Get host compilation flags for the target;
- Get target NuttX configuration;
- Get target OS version, hostname, build and architecture;
- Capable of adding custom, vendor specific, information. Currently gathering only Espressif related info:
  - Get the bootloader version of detected image files;
  - Get the version of different toolchains used by Espressif chips;
  - Get Esptool version.
2023-05-25 11:04:39 -03:00

351 lines
9.8 KiB
C

/****************************************************************************
* apps/testing/nxdiag/nxdiag.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <unistd.h>
#include <nuttx/config.h>
#include <nuttx/version.h>
#include "sysinfo.h"
/****************************************************************************
* Private Data
****************************************************************************/
/* Valid Command Line Arguments */
static const char *g_valid_args[] =
{
"-h",
"--help",
"-n",
"--nuttx",
#ifdef CONFIG_TESTING_NXDIAG_COMP_FLAGS
"-f",
"--flags",
#endif
#ifdef CONFIG_TESTING_NXDIAG_CONF
"-c",
"--config",
#endif
"-o",
"--host-os",
#ifdef CONFIG_TESTING_NXDIAG_HOST_PATH
"-p",
"--host-path",
#endif
#ifdef CONFIG_TESTING_NXDIAG_HOST_PACKAGES
"-k",
"--host-packages",
#endif
#ifdef CONFIG_TESTING_NXDIAG_HOST_MODULES
"-m",
"--host-modules",
#endif
"-v",
"--vendor-specific",
"--all"
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: search_str_in_arr
*
* Description:
* Search for a string in an array of strings.
*
* Input Parameters:
* size - Size of the array.
* arr - Array of strings.
* str - String to search for.
*
* Returned Value:
* True if string is found, false otherwise.
*
****************************************************************************/
bool search_str_in_arr(int size, char *arr[], char *str)
{
int i;
for (i = 0; i < size; i++)
{
if (strcmp(arr[i], str) == 0)
{
return true;
}
}
return false;
}
/****************************************************************************
* Name: are_valid_args
*
* Description:
* Check if provided command line arguments are valid. Valid arguments are
* defined in g_valid_args array.
*
* Input Parameters:
* argc - Number of arguments.
* argv - Array of arguments.
*
* Returned Value:
* True if all arguments are valid, false otherwise.
*
****************************************************************************/
bool are_valid_args(int argc, char *argv[])
{
int i;
for (i = 1; i < argc; i++)
{
if (!search_str_in_arr(nitems(g_valid_args),
(char **)g_valid_args, argv[i]))
{
return false;
}
}
return true;
}
/****************************************************************************
* Name: print_array
*
* Description:
* Print a constant array of strings.
*
* Input Parameters:
* arr - Array of strings.
*
* Returned Value:
* None.
*
****************************************************************************/
void print_array(const char *arr[], int size)
{
int i;
for (i = 0; i < size; i++)
{
printf("\t%s\n", arr[i]);
}
printf("\n");
}
/****************************************************************************
* Name: print_array
*
* Description:
* Print an array of strings.
*
* Input Parameters:
* arr - Array of strings.
*
* Returned Value:
* None.
*
****************************************************************************/
static void print_usage(char *prg)
{
fprintf(stderr, "%s - Get host and target system debug information.\n",
prg);
fprintf(stderr, "\nUsage: %s [options]\n", prg);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -h \
Show this message\n");
fprintf(stderr, " -n, --nuttx \
Output the NuttX operational system information.\n");
#ifdef CONFIG_TESTING_NXDIAG_COMP_FLAGS
fprintf(stderr, " -f, --flags \
Output the NuttX compilation and linker flags used.\n");
#endif
#ifdef CONFIG_TESTING_NXDIAG_CONF
fprintf(stderr, " -c, --config \
Output the NuttX configuration options used.\n");
#endif
fprintf(stderr, " -o, --host-os \
Output the host system operational system information.\n");
#ifdef CONFIG_TESTING_NXDIAG_HOST_PATH
fprintf(stderr, " -p, --host-path \
Output the host PATH environment variable.\n");
#endif
#ifdef CONFIG_TESTING_NXDIAG_HOST_PACKAGES
fprintf(stderr, " -k, --host-packages \
Output the host installed system packages.\n");
#endif
#ifdef CONFIG_TESTING_NXDIAG_HOST_MODULES
fprintf(stderr, " -m, --host-modules \
Output the host installed Python modules.\n");
#endif
fprintf(stderr, " -v, --vendor-specific \
Output vendor specific information.\n");
fprintf(stderr, " --all \
Output all available information.\n");
fprintf(stderr, "\n");
}
/****************************************************************************
* Public Functions
****************************************************************************/
int main(int argc, char *argv[])
{
if (argc == 1 || !are_valid_args(argc, argv))
{
print_usage(argv[0]);
exit(EXIT_FAILURE);
}
if (search_str_in_arr(argc, argv, "-h") ||
search_str_in_arr(argc, argv, "--help"))
{
print_usage(argv[0]);
exit(EXIT_SUCCESS);
}
printf("Nxdiag Report:\n\n");
/* NuttX Info */
if (search_str_in_arr(argc, argv, "-n") ||
search_str_in_arr(argc, argv, "--nuttx") ||
search_str_in_arr(argc, argv, "--all"))
{
char hostname[HOST_NAME_MAX];
gethostname(hostname, HOST_NAME_MAX);
hostname[HOST_NAME_MAX - 1] = '\0';
printf("NuttX RTOS info:\n");
printf("\tHostname: %s\n", hostname);
printf("\tRelease: %s\n", CONFIG_VERSION_STRING);
#if defined(__DATE__) && defined(__TIME__)
printf("\tBuild: %s %s %s\n",
CONFIG_VERSION_BUILD, __DATE__, __TIME__);
#else
printf("\tBuild: %s\n", CONFIG_VERSION_BUILD);
#endif
printf("\tArch: %s\n\n", CONFIG_ARCH);
}
#ifdef CONFIG_TESTING_NXDIAG_COMP_FLAGS
if (search_str_in_arr(argc, argv, "-f") ||
search_str_in_arr(argc, argv, "--flags") ||
search_str_in_arr(argc, argv, "--all"))
{
printf("NuttX CFLAGS:\n");
print_array(NUTTX_CFLAGS, NUTTX_CFLAGS_ARRAY_SIZE);
printf("NuttX CXXFLAGS:\n");
print_array(NUTTX_CXXFLAGS, NUTTX_CXXFLAGS_ARRAY_SIZE);
printf("NuttX LDFLAGS:\n");
print_array(NUTTX_LDFLAGS, NUTTX_LDFLAGS_ARRAY_SIZE);
}
#endif
#ifdef CONFIG_TESTING_NXDIAG_CONF
if (search_str_in_arr(argc, argv, "-c") ||
search_str_in_arr(argc, argv, "--config") ||
search_str_in_arr(argc, argv, "--all"))
{
printf("NuttX configuration options:\n");
print_array(NUTTX_CONFIG, NUTTX_CONFIG_ARRAY_SIZE);
}
#endif
/* Host Info */
if (search_str_in_arr(argc, argv, "-o") ||
search_str_in_arr(argc, argv, "--host-os") ||
search_str_in_arr(argc, argv, "--all"))
{
printf("Host system OS:\n");
printf("\t%s\n\n", OS_VERSION);
}
#ifdef CONFIG_TESTING_NXDIAG_HOST_PATH
if (search_str_in_arr(argc, argv, "-p") ||
search_str_in_arr(argc, argv, "--host-path") ||
search_str_in_arr(argc, argv, "--all"))
{
printf("Host system PATH:\n");
print_array(SYSTEM_PATH, SYSTEM_PATH_ARRAY_SIZE);
}
#endif
#ifdef CONFIG_TESTING_NXDIAG_HOST_PACKAGES
if (search_str_in_arr(argc, argv, "-k") ||
search_str_in_arr(argc, argv, "--host-packages") ||
search_str_in_arr(argc, argv, "--all"))
{
printf("Host system installed packages:\n");
print_array(INSTALLED_PACKAGES, INSTALLED_PACKAGES_ARRAY_SIZE);
}
#endif
#ifdef CONFIG_TESTING_NXDIAG_HOST_MODULES
if (search_str_in_arr(argc, argv, "-m") ||
search_str_in_arr(argc, argv, "--host-modules") ||
search_str_in_arr(argc, argv, "--all"))
{
printf("Host system installed python modules:\n");
print_array(PYTHON_MODULES, PYTHON_MODULES_ARRAY_SIZE);
}
#endif
/* Vendor Specific Info */
if (search_str_in_arr(argc, argv, "-v") ||
search_str_in_arr(argc, argv, "--vendor-specific") ||
search_str_in_arr(argc, argv, "--all"))
{
/* Please don't forget to add the vendor specific information
* in alphabetical order. Also, please update the documentation
* in Documentation/applications/nxdiag
*/
#ifdef CONFIG_TESTING_NXDIAG_ESPRESSIF
printf("Espressif specific information:\n\n");
printf("Bootloader version:\n");
print_array(ESPRESSIF_BOOTLOADER, ESPRESSIF_BOOTLOADER_ARRAY_SIZE);
printf("Toolchain version:\n");
print_array(ESPRESSIF_TOOLCHAIN, ESPRESSIF_TOOLCHAIN_ARRAY_SIZE);
printf("Esptool version: %s\n\n", ESPRESSIF_ESPTOOL);
#endif
}
return 0;
}