mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Fixed a possible crash in cStateLockLog
This commit is contained in:
		
							
								
								
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -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 | ||||
|   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). | ||||
| - 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 | ||||
|   some text to status.h and skins.h, explaining the locking situation when such | ||||
|   functions are called. | ||||
| - Fixed a possible crash in cStateLockLog. | ||||
|   | ||||
							
								
								
									
										32
									
								
								thread.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user