Skip to content

Commit

Permalink
fs: add backtrace to where file opens
Browse files Browse the repository at this point in the history
Signed-off-by: Xu Xingliang <[email protected]>
  • Loading branch information
XuNeo authored and xiaoxiang781216 committed Jun 24, 2024
1 parent add8b71 commit 69d8a17
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 6 deletions.
1 change: 1 addition & 0 deletions boards/sim/sim/sim/configs/citest/defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ CONFIG_FRAME_POINTER=y
CONFIG_FSUTILS_PASSWD=y
CONFIG_FSUTILS_PASSWD_READONLY=y
CONFIG_FS_AIO=y
CONFIG_FS_BACKTRACE=8
CONFIG_FS_BINFS=y
CONFIG_FS_FAT=y
CONFIG_FS_HOSTFS=y
Expand Down
24 changes: 24 additions & 0 deletions fs/inode/fs_files.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <sched.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>

#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>
Expand Down Expand Up @@ -460,6 +461,8 @@ int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR struct inode *inode,
inode_addref(inode);
}

FS_ADD_BACKTRACE(filep);

#ifdef CONFIG_FDCHECK
return fdcheck_protect(i * CONFIG_NFILE_DESCRIPTORS_PER_BLOCK + j);
#else
Expand Down Expand Up @@ -487,6 +490,27 @@ int file_allocate(FAR struct inode *inode, int oflags, off_t pos,
pos, priv, minfd, addref);
}

FAR char *file_dump_backtrace(FAR struct file *filep, FAR char *buffer,
size_t len)
{
#if CONFIG_FS_BACKTRACE > 0
FAR const char *format = "%0*p ";
int k;

buffer[0] = '\0';
for (k = 0; k < CONFIG_FS_BACKTRACE && filep->f_backtrace[k]; k++)
{
snprintf(buffer + k * FS_BACKTRACE_WIDTH,
len - k * FS_BACKTRACE_WIDTH,
format, FS_BACKTRACE_WIDTH - 1,
filep->f_backtrace[k]);
}
#else
buffer[0] = '\0';
#endif
return buffer;
}

/****************************************************************************
* Name: files_duplist
*
Expand Down
18 changes: 18 additions & 0 deletions fs/inode/inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <dirent.h>
#include <sched.h>

#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
Expand Down Expand Up @@ -65,6 +66,23 @@
} \
while (0)

#if CONFIG_FS_BACKTRACE > 0
# define FS_ADD_BACKTRACE(filep) \
do \
{ \
int n = sched_backtrace(_SCHED_GETTID(), filep->f_backtrace, \
CONFIG_FS_BACKTRACE, \
CONFIG_FS_BACKTRACE_SKIP); \
if (n < CONFIG_FS_BACKTRACE) \
{ \
(filep->f_backtrace)[n] = NULL; \
} \
} \
while (0)
#else
# define FS_ADD_BACKTRACE(filep)
#endif

/****************************************************************************
* Public Types
****************************************************************************/
Expand Down
30 changes: 24 additions & 6 deletions fs/procfs/fs_procfsproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1244,15 +1244,17 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
size_t buflen, off_t offset)
{
FAR struct task_group_s *group = tcb->group;
FAR struct file *filep;
char path[PATH_MAX];
size_t remaining;
size_t linesize;
size_t copysize;
size_t totalsize;
int count;
int i;

FAR struct file *filep;
char path[PATH_MAX];
char backtrace[FS_BACKTRACE_BUFFER_LEN];

DEBUGASSERT(group != NULL);

count = files_countlist(&group->tg_filelist);
Expand All @@ -1265,8 +1267,14 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
totalsize = 0;

linesize = procfs_snprintf(procfile->line, STATUS_LINELEN,
"\n%-3s %-7s %-4s %-9s %s\n",
"FD", "OFLAGS", "TYPE", "POS", "PATH");
"\n%-3s %-7s %-4s %-9s %-14s %s\n",
"FD", "OFLAGS", "TYPE", "POS", "PATH",
#if CONFIG_FS_BACKTRACE > 0
"BACKTRACE"
#else
""
#endif
);
copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
&offset);

Expand Down Expand Up @@ -1298,12 +1306,22 @@ static ssize_t proc_groupfd(FAR struct proc_file_s *procfile,
}

linesize = procfs_snprintf(procfile->line, STATUS_LINELEN,
"%-3d %-7d %-4x %-9ld %s\n",
"%-3d %-7d %-4x %-9ld %-14s %s\n",
i, filep->f_oflags,
INODE_GET_TYPE(filep->f_inode),
(long)filep->f_pos, path);
(long)filep->f_pos, path,
file_dump_backtrace(filep,
backtrace,
sizeof(backtrace)
)
);
copysize = procfs_memcpy(procfile->line, linesize,
buffer, remaining, &offset);
if (linesize + 1 == STATUS_LINELEN)
{
procfile->line[STATUS_LINELEN - 2] = '\n';
linesize = STATUS_LINELEN;
}

totalsize += copysize;
buffer += copysize;
Expand Down
13 changes: 13 additions & 0 deletions fs/vfs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,16 @@ config SIGNAL_FD_NPOLLWAITERS
Maximum number of threads that can be waiting on poll()

endif # SIGNAL_FD

config FS_BACKTRACE
int "VFS backtrace"
default 0
---help---
Add backtrace to vfs file open.

config FS_BACKTRACE_SKIP
int "Backtrace to skip"
default 2
depends on FS_BACKTRACE > 0
---help---
Skip depth of backtrace.
1 change: 1 addition & 0 deletions fs/vfs/fs_dup2.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ int file_dup3(FAR struct file *filep1, FAR struct file *filep2, int flags)
filep2->f_tag_fdcheck = filep1->f_tag_fdcheck;
#endif

FS_ADD_BACKTRACE(filep2);
return OK;
}

Expand Down
21 changes: 21 additions & 0 deletions include/nuttx/fs/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@
#define CH_STAT_ATIME (1 << 3)
#define CH_STAT_MTIME (1 << 4)

#define FS_BACKTRACE_WIDTH (sizeof(uintptr_t) * 2 + 3) /* 3: ' 0x' prefix */
#define FS_BACKTRACE_BUFFER_LEN (CONFIG_FS_BACKTRACE * FS_BACKTRACE_WIDTH + 1)

/****************************************************************************
* Public Type Definitions
****************************************************************************/
Expand Down Expand Up @@ -475,6 +478,10 @@ struct file
#ifdef CONFIG_FDCHECK
uint8_t f_tag_fdcheck; /* File owner fdcheck tag, init to 0 */
#endif

#if CONFIG_FS_BACKTRACE > 0
FAR void *f_backtrace[CONFIG_FS_BACKTRACE]; /* Backtrace to while file opens */
#endif
};

/* This defines a two layer array of files indexed by the file descriptor.
Expand Down Expand Up @@ -946,6 +953,20 @@ int file_allocate_from_tcb(FAR struct tcb_s *tcb, FAR struct inode *inode,
int file_allocate(FAR struct inode *inode, int oflags, off_t pos,
FAR void *priv, int minfd, bool addref);

/****************************************************************************
* Name: file_dump_backtrace
*
* Description:
* Dump the backtrace of the file open to given buffer.
*
* Returned Value:
* Returns the backtrace string, it could be empty.
*
****************************************************************************/

FAR char *file_dump_backtrace(FAR struct file *filep, FAR char *buffer,
size_t len);

/****************************************************************************
* Name: file_dup
*
Expand Down

0 comments on commit 69d8a17

Please sign in to comment.