procfs: add heapcheck flag

1 for open heapcheck, 0 for close
echo 1 > /proc/xxx/heapcheck
echo 0 > /proc/xxx/heapcheck

Signed-off-by: haopengxiang <haopengxiang@xiaomi.com>
This commit is contained in:
haopengxiang 2022-04-29 14:10:11 +08:00 committed by Xiang Xiao
parent 4bb393a24e
commit 9bb5148d10

View File

@ -92,6 +92,9 @@ enum proc_node_e
#endif
#if CONFIG_MM_BACKTRACE >= 0
PROC_HEAP, /* Task heap info */
#endif
#ifdef CONFIG_DEBUG_MM
PROC_HEAP_CHECK, /* Task heap check flag */
#endif
PROC_STACK, /* Task stack info */
PROC_GROUP, /* Group directory */
@ -183,6 +186,14 @@ static ssize_t proc_heap(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer,
size_t buflen, off_t offset);
#endif
#ifdef CONFIG_DEBUG_MM
static ssize_t proc_heapcheck(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer,
size_t buflen, off_t offset);
static ssize_t proc_heapcheck_write(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR const char *buffer,
size_t buflen, off_t offset);
#endif
static ssize_t proc_stack(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer, size_t buflen,
off_t offset);
@ -206,7 +217,8 @@ static int proc_open(FAR struct file *filep, FAR const char *relpath,
static int proc_close(FAR struct file *filep);
static ssize_t proc_read(FAR struct file *filep, FAR char *buffer,
size_t buflen);
static ssize_t proc_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen);
static int proc_dup(FAR const struct file *oldp,
FAR struct file *newp);
@ -236,7 +248,7 @@ const struct procfs_operations proc_operations =
proc_open, /* open */
proc_close, /* close */
proc_read, /* read */
NULL, /* write */
proc_write, /* write */
proc_dup, /* dup */
@ -286,6 +298,13 @@ static const struct proc_node_s g_heap =
};
#endif
#ifdef CONFIG_DEBUG_MM
static const struct proc_node_s g_heapcheck =
{
"heapcheck", "heapcheck", (uint8_t)PROC_HEAP_CHECK, DTYPE_FILE /* Task heap info */
};
#endif
static const struct proc_node_s g_stack =
{
"stack", "stack", (uint8_t)PROC_STACK, DTYPE_FILE /* Task stack info */
@ -328,6 +347,9 @@ static FAR const struct proc_node_s * const g_nodeinfo[] =
#endif
#if CONFIG_MM_BACKTRACE >= 0
&g_heap, /* Task heap info */
#endif
#ifdef CONFIG_DEBUG_MM
&g_heapcheck, /* Task heap check flag */
#endif
&g_stack, /* Task stack info */
&g_group, /* Group directory */
@ -354,6 +376,9 @@ static const struct proc_node_s * const g_level0info[] =
#endif
#if CONFIG_MM_BACKTRACE >= 0
&g_heap, /* Task heap info */
#endif
#ifdef CONFIG_DEBUG_MM
&g_heapcheck, /* Task heap check flag */
#endif
&g_stack, /* Task stack info */
&g_group, /* Group directory */
@ -952,6 +977,54 @@ static ssize_t proc_heap(FAR struct proc_file_s *procfile,
}
#endif
#ifdef CONFIG_DEBUG_MM
static ssize_t proc_heapcheck(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb, FAR char *buffer,
size_t buflen, off_t offset)
{
size_t remaining = buflen;
size_t linesize;
size_t copysize;
size_t totalsize = 0;
size_t heapcheck = 0;
if (tcb->flags & TCB_FLAG_HEAPCHECK)
{
heapcheck = 1;
}
linesize = procfs_snprintf(procfile->line, STATUS_LINELEN, "%-12s%d\n",
"HeapCheck:", heapcheck);
copysize = procfs_memcpy(procfile->line, linesize, buffer, remaining,
&offset);
totalsize += copysize;
return totalsize;
}
static ssize_t proc_heapcheck_write(FAR struct proc_file_s *procfile,
FAR struct tcb_s *tcb,
FAR const char *buffer,
size_t buflen, off_t offset)
{
switch (atoi(buffer))
{
case 0:
tcb->flags &= ~TCB_FLAG_HEAPCHECK;
break;
case 1:
tcb->flags |= TCB_FLAG_HEAPCHECK;
break;
default:
ferr("ERROR: invalid argument\n");
return -EINVAL;
break;
}
return buflen;
}
#endif
/****************************************************************************
* Name: proc_stack
****************************************************************************/
@ -1407,18 +1480,6 @@ static int proc_open(FAR struct file *filep, FAR const char *relpath,
finfo("Open '%s'\n", relpath);
/* PROCFS is read-only. Any attempt to open with any kind of write
* access is not permitted.
*
* REVISIT: Write-able proc files could be quite useful.
*/
if ((oflags & O_WRONLY) != 0 || (oflags & O_RDONLY) == 0)
{
ferr("ERROR: Only O_RDONLY supported\n");
return -EACCES;
}
/* The first segment of the relative path should be a task/thread ID or
* the string "self".
*/
@ -1579,6 +1640,11 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer,
case PROC_HEAP: /* Task heap info */
ret = proc_heap(procfile, tcb, buffer, buflen, filep->f_pos);
break;
#endif
#ifdef CONFIG_DEBUG_MM
case PROC_HEAP_CHECK: /* Task heap check flag */
ret = proc_heapcheck(procfile, tcb, buffer, buflen, filep->f_pos);
break;
#endif
case PROC_STACK: /* Task stack info */
ret = proc_stack(procfile, tcb, buffer, buflen, filep->f_pos);
@ -1613,6 +1679,50 @@ static ssize_t proc_read(FAR struct file *filep, FAR char *buffer,
return ret;
}
/****************************************************************************
* Name: proc_write
****************************************************************************/
static ssize_t proc_write(FAR struct file *filep, FAR const char *buffer,
size_t buflen)
{
FAR struct proc_file_s *procfile;
FAR struct tcb_s *tcb;
ssize_t ret;
DEBUGASSERT(filep != NULL && buffer != NULL && buflen > 0);
procfile = (FAR struct proc_file_s *)filep->f_priv;
DEBUGASSERT(procfile != NULL);
/* Verify that the thread is still valid */
tcb = nxsched_get_tcb(procfile->pid);
if (tcb == NULL)
{
ferr("ERROR: PID %d is not valid\n", (int)procfile->pid);
return -ENODEV;
}
/* Provide the requested data */
switch (procfile->node->node)
{
#ifdef CONFIG_DEBUG_MM
case PROC_HEAP_CHECK:
ret = proc_heapcheck_write(procfile, tcb, buffer, buflen,
filep->f_pos);
break;
#endif
default:
ret = -EINVAL;
break;
}
return ret;
}
/****************************************************************************
* Name: proc_dup
*