summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2017-06-23 09:03:19 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2017-06-23 09:03:19 +0200
commit56117751a86636c9df5059dbecc296006b093f25 (patch)
tree704f25ae854598ff5610c98d5493c3bc45f83d47 /thread.c
parent1bce4993838365a839c58ea3c3a9452298c8ba8c (diff)
downloadvdr-56117751a86636c9df5059dbecc296006b093f25.tar.gz
vdr-56117751a86636c9df5059dbecc296006b093f25.tar.bz2
Fixed a possible crash in cStateLockLog
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/thread.c b/thread.c
index 27536791..5ab5f615 100644
--- a/thread.c
+++ b/thread.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@@ -558,6 +558,7 @@ cString cBackTrace::GetCaller(int Level, bool Mangled)
#ifdef DEBUG_LOCKSEQ
#define SLL_SIZE 20 // the number 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_WRITE_FLAG 0x80000000
#define SLL_LOCK_FLAG 0x40000000
@@ -569,7 +570,7 @@ private:
cVector<int> flags;
tThreadId logThreadIds[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
char logCaller[SLL_SIZE][SLL_LENGTH];
#endif
@@ -644,15 +645,32 @@ void cStateLockLog::Check(const char *Name, bool Lock, bool Write)
int b = 1 << n;
cMutexLock MutexLock(&mutex);
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 (Lock) {
+ if (AvailableIndex < 0) {
Index = threadIds.Size();
threadIds.Append(ThreadId);
flags.Append(0);
}
- else
- return;
+ else {
+ 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;
if (Lock) {
@@ -667,6 +685,8 @@ void cStateLockLog::Check(const char *Name, bool Lock, bool Write)
flags[Index] &= ~b;
logThreadIds[logIndex] = ThreadId;
logFlags[logIndex] = flags[Index] | (Write ? SLL_WRITE_FLAG : 0) | (Lock ? SLL_LOCK_FLAG : 0);
+ if (flags[Index] == 0)
+ threadIds[Index] = 0;
#ifdef DEBUG_LOCKCALL
strn0cpy(logCaller[logIndex], cBackTrace::GetCaller(Lock ? 3 : 5, true), SLL_LENGTH);
#endif