1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Fixed a possible crash in cStateLockLog

This commit is contained in:
Klaus Schmidinger 2017-06-23 09:03:19 +02:00
parent 1bce499383
commit 56117751a8
2 changed files with 28 additions and 7 deletions

View File

@ -9130,7 +9130,7 @@ Video Disk Recorder Revision History
before including tools.h in case some plugin needs to use the STL and gets error before including tools.h in case some plugin needs to use the STL and gets error
messages regarding one of the template functions defined in tools.h. messages regarding one of the template functions defined in tools.h.
2017-06-19: Version 2.3.8 2017-06-23: Version 2.3.8
- Updated links in the INSTALL file (thanks to Chris Mayo). - Updated links in the INSTALL file (thanks to Chris Mayo).
- Fixed detecting whether a CAM replies to queries, which didn't work on some systems - Fixed detecting whether a CAM replies to queries, which didn't work on some systems
@ -9138,3 +9138,4 @@ Video Disk Recorder Revision History
- Added some missing locks when calling functions from cStatus or cSkin*, and added - Added some missing locks when calling functions from cStatus or cSkin*, and added
some text to status.h and skins.h, explaining the locking situation when such some text to status.h and skins.h, explaining the locking situation when such
functions are called. functions are called.
- Fixed a possible crash in cStateLockLog.

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: thread.c 4.9 2017/06/09 08:27:22 kls Exp $ * $Id: thread.c 4.10 2017/06/22 15:10:42 kls Exp $
*/ */
#include "thread.h" #include "thread.h"
@ -558,6 +558,7 @@ cString cBackTrace::GetCaller(int Level, bool Mangled)
#ifdef DEBUG_LOCKSEQ #ifdef DEBUG_LOCKSEQ
#define SLL_SIZE 20 // the number of log entries #define SLL_SIZE 20 // the number of log entries
#define SLL_LENGTH 512 // the maximum length of log entries #define SLL_LENGTH 512 // the maximum length of log entries
#define SLL_THREADS 20 // the maximum number of threads holding locks at the same time (typically well below 10)
#define SLL_MAX_LIST 9 // max. number of lists to log #define SLL_MAX_LIST 9 // max. number of lists to log
#define SLL_WRITE_FLAG 0x80000000 #define SLL_WRITE_FLAG 0x80000000
#define SLL_LOCK_FLAG 0x40000000 #define SLL_LOCK_FLAG 0x40000000
@ -569,7 +570,7 @@ private:
cVector<int> flags; cVector<int> flags;
tThreadId logThreadIds[SLL_SIZE]; tThreadId logThreadIds[SLL_SIZE];
int logFlags[SLL_SIZE]; int logFlags[SLL_SIZE];
uint8_t logCounter[SLL_SIZE][SLL_MAX_LIST]; uint8_t logCounter[SLL_THREADS][SLL_MAX_LIST];
#ifdef DEBUG_LOCKCALL #ifdef DEBUG_LOCKCALL
char logCaller[SLL_SIZE][SLL_LENGTH]; char logCaller[SLL_SIZE][SLL_LENGTH];
#endif #endif
@ -644,15 +645,32 @@ void cStateLockLog::Check(const char *Name, bool Lock, bool Write)
int b = 1 << n; int b = 1 << n;
cMutexLock MutexLock(&mutex); cMutexLock MutexLock(&mutex);
tThreadId ThreadId = cThread::ThreadId(); tThreadId ThreadId = cThread::ThreadId();
int Index = threadIds.IndexOf(ThreadId); int Index = -1;
int AvailableIndex = -1;
for (int i = 0; i < threadIds.Size(); i++) {
if (ThreadId == threadIds[i]) {
Index = i;
break;
}
if (threadIds[i] == 0)
AvailableIndex = i;
}
if (Index < 0) { if (Index < 0) {
if (Lock) { if (AvailableIndex < 0) {
Index = threadIds.Size(); Index = threadIds.Size();
threadIds.Append(ThreadId); threadIds.Append(ThreadId);
flags.Append(0); flags.Append(0);
} }
else else {
return; Index = AvailableIndex;
threadIds[Index] = ThreadId;
}
}
if (Index >= SLL_THREADS) {
// should never happen!
esyslog("ERROR: too many threads holding list locks at the same time - stopped logging locks!");
dumped = true;
return;
} }
bool DoDump = false; bool DoDump = false;
if (Lock) { if (Lock) {
@ -667,6 +685,8 @@ void cStateLockLog::Check(const char *Name, bool Lock, bool Write)
flags[Index] &= ~b; flags[Index] &= ~b;
logThreadIds[logIndex] = ThreadId; logThreadIds[logIndex] = ThreadId;
logFlags[logIndex] = flags[Index] | (Write ? SLL_WRITE_FLAG : 0) | (Lock ? SLL_LOCK_FLAG : 0); logFlags[logIndex] = flags[Index] | (Write ? SLL_WRITE_FLAG : 0) | (Lock ? SLL_LOCK_FLAG : 0);
if (flags[Index] == 0)
threadIds[Index] = 0;
#ifdef DEBUG_LOCKCALL #ifdef DEBUG_LOCKCALL
strn0cpy(logCaller[logIndex], cBackTrace::GetCaller(Lock ? 3 : 5, true), SLL_LENGTH); strn0cpy(logCaller[logIndex], cBackTrace::GetCaller(Lock ? 3 : 5, true), SLL_LENGTH);
#endif #endif