mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
VFS: Add debugging outputs for select() related functions
This commit is contained in:
@@ -18,12 +18,46 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_USE_ONLY_LWIP_SELECT
|
#ifdef CONFIG_USE_ONLY_LWIP_SELECT
|
||||||
#include "lwip/sockets.h"
|
#include "lwip/sockets.h"
|
||||||
#endif
|
|
||||||
|
#ifdef CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT
|
||||||
|
#define LOG_LOCAL_LEVEL ESP_LOG_NONE
|
||||||
|
#endif //CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
static const char *TAG = "newlib_select";
|
||||||
|
|
||||||
|
static void log_fd_set(const char *fds_name, const fd_set *fds)
|
||||||
|
{
|
||||||
|
if (fds_name && fds) {
|
||||||
|
ESP_LOGD(TAG, "FDs in %s =", fds_name);
|
||||||
|
for (int i = 0; i < MAX_FDS; ++i) {
|
||||||
|
if (FD_ISSET(i, fds)) {
|
||||||
|
ESP_LOGD(TAG, "%d", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //CONFIG_USE_ONLY_LWIP_SELECT
|
||||||
|
|
||||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)
|
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_USE_ONLY_LWIP_SELECT
|
#ifdef CONFIG_USE_ONLY_LWIP_SELECT
|
||||||
return lwip_select(nfds, readfds, writefds, errorfds, timeout);
|
ESP_LOGD(TAG, "lwip_select starts with nfds = %d", nfds);
|
||||||
|
if (timeout) {
|
||||||
|
ESP_LOGD(TAG, "timeout is %lds + %ldus", timeout->tv_sec, timeout->tv_usec);
|
||||||
|
}
|
||||||
|
log_fd_set("readfds", readfds);
|
||||||
|
log_fd_set("writefds", writefds);
|
||||||
|
log_fd_set("errorfds", errorfds);
|
||||||
|
|
||||||
|
int ret = lwip_select(nfds, readfds, writefds, errorfds, timeout);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "lwip_select returns %d", ret);
|
||||||
|
log_fd_set("readfds", readfds);
|
||||||
|
log_fd_set("writefds", writefds);
|
||||||
|
log_fd_set("errorfds", errorfds);
|
||||||
|
|
||||||
|
return ret;
|
||||||
#else
|
#else
|
||||||
return esp_vfs_select(nfds, readfds, writefds, errorfds, timeout);
|
return esp_vfs_select(nfds, readfds, writefds, errorfds, timeout);
|
||||||
#endif
|
#endif
|
||||||
|
12
components/vfs/Kconfig
Normal file
12
components/vfs/Kconfig
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
menu "Virtual file system"
|
||||||
|
|
||||||
|
config SUPPRESS_SELECT_DEBUG_OUTPUT
|
||||||
|
bool "Suppress select() related debug outputs"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Select() related functions might produce an unconveniently lot of
|
||||||
|
debug outputs when one sets the default log level to DEBUG or higher.
|
||||||
|
It is possible to suppress these debug outputs by enabling this
|
||||||
|
option.
|
||||||
|
|
||||||
|
endmenu
|
@@ -25,8 +25,15 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include "esp_vfs.h"
|
#include "esp_vfs.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT
|
||||||
|
#define LOG_LOCAL_LEVEL ESP_LOG_NONE
|
||||||
|
#endif //CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
static const char *TAG = "vfs";
|
||||||
|
|
||||||
#define VFS_MAX_COUNT 8 /* max number of VFS entries (registered filesystems) */
|
#define VFS_MAX_COUNT 8 /* max number of VFS entries (registered filesystems) */
|
||||||
#define LEN_PATH_PREFIX_IGNORED SIZE_MAX /* special length value for VFS which is never recognised by open() */
|
#define LEN_PATH_PREFIX_IGNORED SIZE_MAX /* special length value for VFS which is never recognised by open() */
|
||||||
#define FD_TABLE_ENTRY_UNUSED (fd_table_t) { .permanent = false, .vfs_index = -1, .local_fd = -1 }
|
#define FD_TABLE_ENTRY_UNUSED (fd_table_t) { .permanent = false, .vfs_index = -1, .local_fd = -1 }
|
||||||
@@ -127,6 +134,7 @@ esp_err_t esp_vfs_register(const char* base_path, const esp_vfs_t* vfs, void* ct
|
|||||||
esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd, int max_fd)
|
esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd, int max_fd)
|
||||||
{
|
{
|
||||||
if (min_fd < 0 || max_fd < 0 || min_fd > MAX_FDS || max_fd > MAX_FDS || min_fd > max_fd) {
|
if (min_fd < 0 || max_fd < 0 || min_fd > MAX_FDS || max_fd > MAX_FDS || min_fd > max_fd) {
|
||||||
|
ESP_LOGD(TAG, "Invalid arguments: esp_vfs_register_fd_range(0x%x, 0x%x, %d, %d)", (int) vfs, (int) ctx, min_fd, max_fd);
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +153,7 @@ esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_lock_release(&s_fd_table_lock);
|
_lock_release(&s_fd_table_lock);
|
||||||
|
ESP_LOGD(TAG, "esp_vfs_register_fd_range cannot set fd %d (used by other VFS)", i);
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
s_fd_table[i].permanent = true;
|
s_fd_table[i].permanent = true;
|
||||||
@@ -154,6 +163,8 @@ esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd,
|
|||||||
_lock_release(&s_fd_table_lock);
|
_lock_release(&s_fd_table_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "esp_vfs_register_fd_range is successful for range <%d; %d) and VFS ID %d", min_fd, max_fd, index);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,6 +207,7 @@ esp_err_t esp_vfs_unregister(const char* base_path)
|
|||||||
esp_err_t esp_vfs_register_fd(esp_vfs_id_t vfs_id, int *fd)
|
esp_err_t esp_vfs_register_fd(esp_vfs_id_t vfs_id, int *fd)
|
||||||
{
|
{
|
||||||
if (vfs_id < 0 || vfs_id >= s_vfs_count || fd == NULL) {
|
if (vfs_id < 0 || vfs_id >= s_vfs_count || fd == NULL) {
|
||||||
|
ESP_LOGD(TAG, "Invalid arguments for esp_vfs_register_fd(%d, 0x%x)", vfs_id, (int) fd);
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +225,8 @@ esp_err_t esp_vfs_register_fd(esp_vfs_id_t vfs_id, int *fd)
|
|||||||
}
|
}
|
||||||
_lock_release(&s_fd_table_lock);
|
_lock_release(&s_fd_table_lock);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "esp_vfs_register_fd(%d, 0x%x) finished with %s", vfs_id, (int) fd, esp_err_to_name(ret));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +235,7 @@ esp_err_t esp_vfs_unregister_fd(esp_vfs_id_t vfs_id, int fd)
|
|||||||
esp_err_t ret = ESP_ERR_INVALID_ARG;
|
esp_err_t ret = ESP_ERR_INVALID_ARG;
|
||||||
|
|
||||||
if (vfs_id < 0 || vfs_id >= s_vfs_count || fd < 0 || fd >= MAX_FDS) {
|
if (vfs_id < 0 || vfs_id >= s_vfs_count || fd < 0 || fd >= MAX_FDS) {
|
||||||
|
ESP_LOGD(TAG, "Invalid arguments for esp_vfs_unregister_fd(%d, %d)", vfs_id, fd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,6 +247,8 @@ esp_err_t esp_vfs_unregister_fd(esp_vfs_id_t vfs_id, int fd)
|
|||||||
}
|
}
|
||||||
_lock_release(&s_fd_table_lock);
|
_lock_release(&s_fd_table_lock);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "esp_vfs_unregister_fd(%d, %d) finished with %s", vfs_id, fd, esp_err_to_name(ret));
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,7 +407,7 @@ int esp_vfs_open(struct _reent *r, const char * path, int flags, int mode)
|
|||||||
_lock_release(&s_fd_table_lock);
|
_lock_release(&s_fd_table_lock);
|
||||||
int ret;
|
int ret;
|
||||||
CHECK_AND_CALL(ret, r, vfs, close, fd_within_vfs);
|
CHECK_AND_CALL(ret, r, vfs, close, fd_within_vfs);
|
||||||
(void) ret; // remove "set but not used" warning
|
(void) ret; // remove "set but not used" warning
|
||||||
__errno_r(r) = ENOMEM;
|
__errno_r(r) = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -730,14 +747,17 @@ static int set_global_fd_sets(const fds_triple_t *vfs_fds_triple, int size, fd_s
|
|||||||
for (int fd = 0; fd < MAX_FDS; ++fd) {
|
for (int fd = 0; fd < MAX_FDS; ++fd) {
|
||||||
const int local_fd = s_fd_table[fd].local_fd; // single read -> no locking is required
|
const int local_fd = s_fd_table[fd].local_fd; // single read -> no locking is required
|
||||||
if (readfds && FD_ISSET(local_fd, &item->readfds)) {
|
if (readfds && FD_ISSET(local_fd, &item->readfds)) {
|
||||||
|
ESP_LOGD(TAG, "FD %d in readfds was set from VFS ID %d", fd, i);
|
||||||
FD_SET(fd, readfds);
|
FD_SET(fd, readfds);
|
||||||
++ret;
|
++ret;
|
||||||
}
|
}
|
||||||
if (writefds && FD_ISSET(local_fd, &item->writefds)) {
|
if (writefds && FD_ISSET(local_fd, &item->writefds)) {
|
||||||
|
ESP_LOGD(TAG, "FD %d in writefds was set from VFS ID %d", fd, i);
|
||||||
FD_SET(fd, writefds);
|
FD_SET(fd, writefds);
|
||||||
++ret;
|
++ret;
|
||||||
}
|
}
|
||||||
if (errorfds && FD_ISSET(local_fd, &item->errorfds)) {
|
if (errorfds && FD_ISSET(local_fd, &item->errorfds)) {
|
||||||
|
ESP_LOGD(TAG, "FD %d in errorfds was set from VFS ID %d", fd, i);
|
||||||
FD_SET(fd, errorfds);
|
FD_SET(fd, errorfds);
|
||||||
++ret;
|
++ret;
|
||||||
}
|
}
|
||||||
@@ -748,17 +768,39 @@ static int set_global_fd_sets(const fds_triple_t *vfs_fds_triple, int size, fd_s
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void esp_vfs_log_fd_set(const char *fds_name, const fd_set *fds)
|
||||||
|
{
|
||||||
|
if (fds_name && fds) {
|
||||||
|
ESP_LOGD(TAG, "FDs in %s =", fds_name);
|
||||||
|
for (int i = 0; i < MAX_FDS; ++i) {
|
||||||
|
if (FD_ISSET(i, fds)) {
|
||||||
|
ESP_LOGD(TAG, "%d", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)
|
int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct _reent* r = __getreent();
|
struct _reent* r = __getreent();
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "esp_vfs_select starts with nfds = %d", nfds);
|
||||||
|
if (timeout) {
|
||||||
|
ESP_LOGD(TAG, "timeout is %lds + %ldus", timeout->tv_sec, timeout->tv_usec);
|
||||||
|
}
|
||||||
|
esp_vfs_log_fd_set("readfds", readfds);
|
||||||
|
esp_vfs_log_fd_set("writefds", writefds);
|
||||||
|
esp_vfs_log_fd_set("errorfds", errorfds);
|
||||||
|
|
||||||
if (nfds > MAX_FDS || nfds < 0) {
|
if (nfds > MAX_FDS || nfds < 0) {
|
||||||
|
ESP_LOGD(TAG, "incorrect nfds");
|
||||||
__errno_r(r) = EINVAL;
|
__errno_r(r) = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_lock_try_acquire(&s_one_select_lock)) {
|
if (_lock_try_acquire(&s_one_select_lock)) {
|
||||||
|
ESP_LOGD(TAG, "concurrent select is not supported");
|
||||||
__errno_r(r) = EINTR;
|
__errno_r(r) = EINTR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -767,6 +809,7 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
|||||||
if ((vfs_fds_triple = calloc(s_vfs_count, sizeof(fds_triple_t))) == NULL) {
|
if ((vfs_fds_triple = calloc(s_vfs_count, sizeof(fds_triple_t))) == NULL) {
|
||||||
__errno_r(r) = ENOMEM;
|
__errno_r(r) = ENOMEM;
|
||||||
_lock_release(&s_one_select_lock);
|
_lock_release(&s_one_select_lock);
|
||||||
|
ESP_LOGD(TAG, "calloc is unsuccessful");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,16 +843,19 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
|||||||
item->isset = true;
|
item->isset = true;
|
||||||
FD_SET(local_fd, &item->readfds);
|
FD_SET(local_fd, &item->readfds);
|
||||||
FD_CLR(fd, readfds);
|
FD_CLR(fd, readfds);
|
||||||
|
ESP_LOGD(TAG, "removing %d from readfds and adding as local FD %d to fd_set of VFS ID %d", fd, local_fd, vfs_index);
|
||||||
}
|
}
|
||||||
if (writefds && FD_ISSET(fd, writefds)) {
|
if (writefds && FD_ISSET(fd, writefds)) {
|
||||||
item->isset = true;
|
item->isset = true;
|
||||||
FD_SET(local_fd, &item->writefds);
|
FD_SET(local_fd, &item->writefds);
|
||||||
FD_CLR(fd, writefds);
|
FD_CLR(fd, writefds);
|
||||||
|
ESP_LOGD(TAG, "removing %d from writefds and adding as local FD %d to fd_set of VFS ID %d", fd, local_fd, vfs_index);
|
||||||
}
|
}
|
||||||
if (errorfds && FD_ISSET(fd, errorfds)) {
|
if (errorfds && FD_ISSET(fd, errorfds)) {
|
||||||
item->isset = true;
|
item->isset = true;
|
||||||
FD_SET(local_fd, &item->errorfds);
|
FD_SET(local_fd, &item->errorfds);
|
||||||
FD_CLR(fd, errorfds);
|
FD_CLR(fd, errorfds);
|
||||||
|
ESP_LOGD(TAG, "removing %d from errorfds and adding as local FD %d to fd_set of VFS ID %d", fd, local_fd, vfs_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,6 +870,7 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
|||||||
free(vfs_fds_triple);
|
free(vfs_fds_triple);
|
||||||
__errno_r(r) = ENOMEM;
|
__errno_r(r) = ENOMEM;
|
||||||
_lock_release(&s_one_select_lock);
|
_lock_release(&s_one_select_lock);
|
||||||
|
ESP_LOGD(TAG, "cannot create s_select_sem");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -835,6 +882,10 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
|||||||
if (vfs && vfs->vfs.start_select && item->isset) {
|
if (vfs && vfs->vfs.start_select && item->isset) {
|
||||||
// call start_select for all non-socket VFSs with has at least one FD set in readfds, writefds, or errorfds
|
// call start_select for all non-socket VFSs with has at least one FD set in readfds, writefds, or errorfds
|
||||||
// note: it can point to socket VFS but item->isset will be false for that
|
// note: it can point to socket VFS but item->isset will be false for that
|
||||||
|
ESP_LOGD(TAG, "calling start_select for VFS ID %d with the following local FDs", i);
|
||||||
|
esp_vfs_log_fd_set("readfds", &item->readfds);
|
||||||
|
esp_vfs_log_fd_set("writefds", &item->writefds);
|
||||||
|
esp_vfs_log_fd_set("errorfds", &item->errorfds);
|
||||||
esp_err_t err = vfs->vfs.start_select(nfds, &item->readfds, &item->writefds, &item->errorfds);
|
esp_err_t err = vfs->vfs.start_select(nfds, &item->readfds, &item->writefds, &item->errorfds);
|
||||||
|
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
@@ -847,13 +898,22 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
|||||||
free(vfs_fds_triple);
|
free(vfs_fds_triple);
|
||||||
__errno_r(r) = ENOMEM;
|
__errno_r(r) = ENOMEM;
|
||||||
_lock_release(&s_one_select_lock);
|
_lock_release(&s_one_select_lock);
|
||||||
|
ESP_LOGD(TAG, "start_select failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socket_select) {
|
if (socket_select) {
|
||||||
|
ESP_LOGD(TAG, "calling socket_select with the following FDs");
|
||||||
|
esp_vfs_log_fd_set("readfds", readfds);
|
||||||
|
esp_vfs_log_fd_set("writefds", writefds);
|
||||||
|
esp_vfs_log_fd_set("errorfds", errorfds);
|
||||||
ret = socket_select(nfds, readfds, writefds, errorfds, timeout);
|
ret = socket_select(nfds, readfds, writefds, errorfds, timeout);
|
||||||
|
ESP_LOGD(TAG, "socket_select returned %d and the FDs are the following", ret);
|
||||||
|
esp_vfs_log_fd_set("readfds", readfds);
|
||||||
|
esp_vfs_log_fd_set("writefds", writefds);
|
||||||
|
esp_vfs_log_fd_set("errorfds", errorfds);
|
||||||
} else {
|
} else {
|
||||||
if (readfds) {
|
if (readfds) {
|
||||||
FD_ZERO(readfds);
|
FD_ZERO(readfds);
|
||||||
@@ -869,7 +929,9 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
|||||||
if (timeout) {
|
if (timeout) {
|
||||||
uint32_t timeout_ms = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
uint32_t timeout_ms = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
|
||||||
ticks_to_wait = timeout_ms / portTICK_PERIOD_MS;
|
ticks_to_wait = timeout_ms / portTICK_PERIOD_MS;
|
||||||
|
ESP_LOGD(TAG, "timeout is %dms", timeout_ms);
|
||||||
}
|
}
|
||||||
|
ESP_LOGD(TAG, "waiting without calling socket_select");
|
||||||
xSemaphoreTake(s_select_sem, ticks_to_wait);
|
xSemaphoreTake(s_select_sem, ticks_to_wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,6 +945,11 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
|||||||
}
|
}
|
||||||
free(vfs_fds_triple);
|
free(vfs_fds_triple);
|
||||||
_lock_release(&s_one_select_lock);
|
_lock_release(&s_one_select_lock);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "esp_vfs_select returns %d", ret);
|
||||||
|
esp_vfs_log_fd_set("readfds", readfds);
|
||||||
|
esp_vfs_log_fd_set("writefds", writefds);
|
||||||
|
esp_vfs_log_fd_set("errorfds", errorfds);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user