Re: Watchdog kicks in, 1.3.28, 1.3.29

Message ID 200508171427.48174.marcel.wiesweg@gmx.de
State New
Headers

Commit Message

Marcel Wiesweg Aug. 17, 2005, 12:27 p.m. UTC
  Am Dienstag 16 August 2005 19:22 schrieb Malte Schröder:
> >>>I will try LD_ASSUME_KERNEL, let's see ...
> >>
> >>Seems to "fix" the problem .. so how can we debug this?
> >
> > See if the problem exists running under gdb as well. If it does, set a
> > breakpoint to the watchdog function (maybe gdb catches SIGALRM before).
> > When the watchdog expires, get a bt from all threads (thread apply all
> > bt) and examine where the main thread is hanging.
> > If the error does not occur, let VDR segfault in Watchdog() (something
> > like (*((int *)0))++; will do this), and examine the core file (set
> > ulimit -c unlimited)
>
> The backtrace is attached (thread 1 moved to top).

The backtrace suggests something is wrong in DvbTuner: Either the poll() in 
thread 2 does not return, or there is some sort of deadlock.
Unfortunately I cannot reproduce the problem here.
First you might try if the attached patch fixes the problem.
If not, please put printfs around Lock() and Unlock() in dvbtuner.c line 129, 
138, 299, 339, and possibly around the poll in line 157 as well, such as

printf("DvbTuner::Set: Now locking mutex\n");
Lock();
printf("DvbTuner::Set: Lockedmutex\n");
...
printf(""DvbTuner::Set: Unlocking mutex");
Unlock();

and capture the output  to a file.

Marcel

>
> > Marcel
  

Comments

Thomas Bartschies Aug. 17, 2005, 7:39 p.m. UTC | #1
Am Mittwoch, 17. August 2005 14:27 schrieb Marcel Wiesweg:
> Am Dienstag 16 August 2005 19:22 schrieb Malte Schröder:
[snip]
> The backtrace suggests something is wrong in DvbTuner: Either the poll() in
> thread 2 does not return, or there is some sort of deadlock.
> Unfortunately I cannot reproduce the problem here.
> First you might try if the attached patch fixes the problem.
> If not, please put printfs around Lock() and Unlock() in dvbtuner.c line
> 129, 138, 299, 339, and possibly around the poll in line 157 as well, such
> as

Hi Marcel,
your dvbtuner patch seems to fix the issue. My vdr runs now for almost
an hour. Before it crashed a few minutes after every new vdr start,
reproducible.

I'll test it now for a few days and then tell you my final verdict. But for 
now, thanks very much.

Regards,
Thomas
  
Malte Schröder Aug. 19, 2005, 4:58 a.m. UTC | #2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Marcel Wiesweg wrote:
>>The backtrace is attached (thread 1 moved to top).
> 
> 
> The backtrace suggests something is wrong in DvbTuner: Either the poll() in 
> thread 2 does not return, or there is some sort of deadlock.
> Unfortunately I cannot reproduce the problem here.
> First you might try if the attached patch fixes the problem.

Thanks, looks like it does :) No crashes/watchdog-restarts yet.
I will do some more testing over the weekend and write here if the
problem arises again.

> If not, please put printfs around Lock() and Unlock() in dvbtuner.c line 129, 
> 138, 299, 339, and possibly around the poll in line 157 as well, such as
> 


- --
- ---------------------------------------
Malte Schröder
MalteSch@gmx.de
ICQ# 68121508
- ---------------------------------------

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFDBWcM4q3E2oMjYtURAl+3AJwJ4hAwrgf+LXHcWEqJzb/+bzxOyQCgss/9
Stu4NsYFfDZaH0uwagydZJM=
=+gn+
-----END PGP SIGNATURE-----
  
Joachim Wilke Aug. 20, 2005, 1:53 p.m. UTC | #3
2005/8/17, Marcel Wiesweg <marcel.wiesweg@gmx.de>:
> First you might try if the attached patch fixes the problem.

Have had the same problems when replaying a DVD. After about 10 min
the watchdog restarted my VDR. The fix solves the issue for me too.
Thanks a lot :o)

Regards,
Joachim.
  
Birgit & Andreas Böttger Aug. 21, 2005, 6:59 a.m. UTC | #4
Marcel Wiesweg schrieb:
> Am Dienstag 16 August 2005 19:22 schrieb Malte Schröder:
>>
>>The backtrace is attached (thread 1 moved to top).
> 
> The backtrace suggests something is wrong in DvbTuner: Either the poll() in 
> thread 2 does not return, or there is some sort of deadlock.
> Unfortunately I cannot reproduce the problem here.
> First you might try if the attached patch fixes the problem.
> 
> Marcel

Your patch works, many thanks!
(vdr-1.3.28, SuSE 9.3, 1x DVB-S 1.3, 2x Budget)

kind regards
Andreas Böttger
  

Patch

--- dvbdevice.c.orig	2005-08-17 13:32:50.000000000 +0200
+++ dvbdevice.c	2005-08-17 14:15:35.000000000 +0200
@@ -83,5 +83,5 @@ 
   cMutex mutex;
   cCondVar locked;
-  cCondWait newSet;
+  cCondVar newSet;
   bool GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs = 0);
   bool SetFrontend(void);
@@ -116,5 +116,6 @@ 
   active = false;
   tunerStatus = tsIdle;
-  newSet.Signal();
+  newSet.Broadcast();
+  locked.Broadcast();
   Cancel(3);
 }
@@ -127,5 +128,6 @@ 
 void cDvbTuner::Set(const cChannel *Channel, bool Tune, bool UseCa)
 {
-  Lock();
+  //Lock();
+  cMutexLock MutexLock(&mutex);
   if (Tune)
      tunerStatus = tsSet;
@@ -136,10 +138,15 @@ 
      startTime = time(NULL);
   channel = *Channel;
-  Unlock();
-  newSet.Signal();
+  //Unlock();
+  //newSet.Signal();
+  newSet.Broadcast();
 }
 
 bool cDvbTuner::Locked(int TimeoutMs)
 {
+  bool isLocked = (tunerStatus >= tsLocked);
+  if (isLocked || !TimeoutMs)
+     return isLocked;
+  
   cMutexLock MutexLock(&mutex);
   if (TimeoutMs && tunerStatus < tsLocked)
@@ -297,12 +304,19 @@ 
   active = true;
   while (active) {
-        Lock();
-        if (tunerStatus == tsSet) {
-           while (GetFrontendEvent(event))
-                 ; // discard stale events
-           tunerStatus = SetFrontend() ? tsTuned : tsIdle;
-           }
-        if (tunerStatus != tsIdle) {
-           while (GetFrontendEvent(event, 10)) {
+        bool hasEvent = GetFrontendEvent(event, 1);
+        
+        cMutexLock MutexLock(&mutex);
+        switch (tunerStatus) {
+        case tsIdle: 
+            break;
+        case tsSet:
+            if (hasEvent)
+               continue;
+            tunerStatus = SetFrontend() ? tsTuned : tsIdle;
+            continue;
+        case tsTuned:
+        case tsLocked:
+        case tsCam:
+            if (hasEvent) {
                  if (event.status & FE_REINIT) {
                     tunerStatus = tsSet;
@@ -310,10 +324,11 @@ 
                     }
                  if (event.status & FE_HAS_LOCK) {
-                    cMutexLock MutexLock(&mutex);
                     tunerStatus = tsLocked;
                     locked.Broadcast();
                     }
+                 continue;
                  }
            }
+        
         if (ciHandler) {
            if (ciHandler->Process() && useCa) {
@@ -337,8 +352,8 @@ 
               tunerStatus = tsLocked;
            }
-        Unlock();
         // in the beginning we loop more often to let the CAM connection start up fast
         if (tunerStatus != tsTuned)
-           newSet.Wait((ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
+           newSet.TimedWait(mutex, (ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
+        
         }
 }