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:
parent
4bb393a24e
commit
9bb5148d10
@ -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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user