pthread_cond_wait() should be an atomic operation in the mutex lock/unlock.
Since the sched_lock() has been wrongly deleted in the previous commit,
the context switch will occurred after the mutex was unlocked:
--------------------------------------------------------------------
Task1(Priority 100) | Task2(Priority 101)
|
pthread_mutex_lock(mutex); |
| |
pthread_cond_wait(cond, mutex) |
| | |
| | |
| ->enter_critical_section() |
| ->pthread_mutex_give(mutex) | ----> pthread_mutex_lock(mutex); // contex switch to high priority task
| | pthread_cond_signal(cond); // signal before wait
| | <---- pthread_mutex_unlock(mutex); // switch back to original task
| ->pthread_sem_take(cond->sem)| // try to wait the signal, Deadlock.
| ->leave_critical_section() |
|
| ->pthread_mutex_take(mutex) |
| |
pthread_mutex_lock(mutex); |
---------------------------------------------------------------------
This PR will bring back sched_lock()/sched_unlock() to avoid context switch to ensure atomicity
Signed-off-by: chao an <anchao@xiaomi.com>
1. the lio_sigsetup() method use a universal sighand instance across all
aiocb instances, but inside the lio_sighandler() method, if one aiocb is
handle finished, then this method will free the sighand instance that
come along with current aiocb instance. thus when handle next aiocb
instance, use-after-free crash will happen. in order to solve this
problem, we make each aiocb instance have their own sighand instance
2. make the lio_listio implementation can pass the
ltp/open_posix_testsuite/lio_listio testcases
3. the modification are referred to https://pubs.opengroup.org/onlinepubs/9699919799/functions/lio_listio.html
Signed-off-by: guoshichao <guoshichao@xiaomi.com>
Testing for overflow by adding a value to a variable to see if it "wraps
around" works only for unsigned integer values, because signed overflow
has undefined behavior according to the C and C++ standards.
Signed-off-by: Mingjie Shen <shen497@purdue.edu>
If cancellation points are enabled, then the following logic is activated in sem_wait(). This causes ECANCELED to be returned every time that sem_wait is called.
int sem_wait(FAR sem_t *sem)
{
...
/* sem_wait() is a cancellation point */
if (enter_cancellation_point())
{
#ifdef CONFIG_CANCELLATION_POINTS
/* If there is a pending cancellation, then do not perform
* the wait. Exit now with ECANCELED.
*/
errcode = ECANCELED;
goto errout_with_cancelpt;
#endif
}
...
Normally this works fine. sem_wait() is the OS API called by the application and will cancel the thread just before it returns to the application. Since it is cancellation point, it should never be called from within the OS.
There there is is one perverse cases where sem_wait() may be nested within another cancellation point. If open() is called, it will attempt to lock a VFS data structure and will eventually call nxmutex_lock(). nxmutex_lock() waits on a semaphore:
int nxmutex_lock(FAR mutex_t *mutex)
{
...
for (; ; )
{
/* Take the semaphore (perhaps waiting) */
ret = _SEM_WAIT(&mutex->sem);
if (ret >= 0)
{
mutex->holder = _SCHED_GETTID();
break;
}
ret = _SEM_ERRVAL(ret);
if (ret != -EINTR && ret != -ECANCELED)
{
break;
}
}
...
}
In the FLAT build, _SEM_WAIT expands to sem_wait(). That causes the error in the logic: It should always expand to nxsem_wait(). That is because sem_wait() is cancellation point and should never be called from with the OS or the C library internally.
The failure occurs because the cancellation point logic in sem_wait() returns -ECANCELED (via _SEM_ERRVAL) because sem_wait() is nested; it needs to return the -ECANCELED error to the outermost cancellation point which is open() in this case. Returning -ECANCELED then causes an infinite loop to occur in nxmutex_lock().
The correct behavior in this case is to call nxsem_wait() instead of sem_wait(). nxsem_wait() is identical to sem_wait() except that it is not a cancelation point. It will return -ECANCELED if the thread is canceled, but only once. So no infinite loop results.
In addition, an nxsem_wait() system call was added to support the call from nxmutex_lock().
This resolves Issue #9695
since symbols defined in arch/elf.h is also used in other case, for example:
CC: pthread/pthread_testcancel.c machine/arm/gnu_unwind_find_exidx.c:32:8: error: unknown type name '__EIT_entry'
32 | static __EIT_entry *__exidx_start_elf;
| ^~~~~~~~~~~
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
1. the getpgrp function can help to pass the ltp/open_posix_teststuite/killpg related testcases
2. Nuttx do not support process group, so we use getpid to implement this
3. the implementation are referred to: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html
Signed-off-by: guoshichao <guoshichao@xiaomi.com>
This patch add an example and pyhton base modules:
1.add memdump.py is an example to analyze memory
usage by python script.
2.add The most basic data structure analysis, like list, etc.
future ideas:
Maybe we can add modules related to "sched, drivers, arch, fs.." to
automatically analyze scripts to debug some problems
References:
linux kernel (https://github.com/torvalds/linux/tree/master/scripts/gdb)
The official manual of gdb (https://sourceware.org/gdb/onlinedocs/gdb/Python-API.html)
Change-Id: Ib9025a0a141cb89f3813526f7c55dcb28de31ed9
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
The following macros
__ARCH_ARM_SRC_STM32F7_HARDWARE_STM32F74XX75XX_FLASH_H
__ARCH_ARM_SRC_STM32L4_HARDWARE_STM32L4X6XX_RCC_H
are used in other header files.
Signed-off-by: Mingjie Shen <shen497@purdue.edu>
In this nested loop, the iteration variable is the same for both loops.
This is a typo and the inner loop should use a new loop variable.
Signed-off-by: Mingjie Shen <shen497@purdue.edu>
Memory pointed by priv may be used (in line 1289) after it is
freed in line 1283.
Fix by adding the missing return statement in error handling.
Signed-off-by: Mingjie Shen <shen497@purdue.edu>
It is used to write the log message to the channel immediately
when the log message is generated in the interrupt context, which
is faster than the normal force callback.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
syslog_force is used to force the syslog output to the
console in interrupt context, but we can use syslog_write
to do the same(and more) thing.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This function will use gcc's function
__builtin_dynamic_object_size and __builtin_object_size
Its function is to obtain the size of the object through compilation,
so as to judge whether there are out-of-bounds operations in commonly used functions.
It should be noted that the option -O2 and above is required to enable this function
Signed-off-by: anjiahao <1090959677@qq.com>
If sendfile() is called with a zero count, it will nevertheless
try to send the data. This is mostly meaningless, it causes
waste of resources, and in some cases delays.
This commit adds special handling for this case, allowing
sendfile to return immediately zero. The new behavior is
in line with the Linux variant of sendfile.
When asserting, automatically analyze whether
there is a deadlock in the thread, and if there
is a deadlock, print out the deadlocked thread.
The principle is to analyze whether there is
a lock ring through the tcb holder.
Signed-off-by: anjiahao <anjiahao@xiaomi.com>