[PATCH 2/2] os: Prevent core dump from being truncated.

Rami Ylimaki ext-rami.ylimaki at nokia.com
Tue Jan 12 06:03:14 PST 2010


The problem fixed by this patch can be reproduced on Linux with the
following steps.
- Access NULL pointer intentionally in ProcessOtherEvent on key press.
- Instead of saving core dump to a file, write it into a pipe.
  echo "|/usr/sbin/my-core-dumper" > /proc/sys/kernel/core_pattern
- Dump the core by pressing a key.

While the core is being dumped into the pipe, the smart schedule timer
will cause a pending SIGALRM. Linux kernel stops writing data to the
pipe when there are pending signals. This causes the core dump to be
truncated. On my system I'm expecting a 6 MB dump but the size will be
60 kB instead. The problem is solved if we block the SIGALRM caused by
expired smart schedule timer.

I haven't been able to reproduce this problem in the following cases.
- Save core dump to a file instead of a pipe.
- kill -SEGV `pidof Xorg`
- Press a key to dump core while gdb is attached to Xorg.
- Give option -dumbSched to Xorg.

Also note that the fix works only when NoTrapSignals has the default
value FALSE. The problem can still be reproduced if error signals
aren't trapped. In addition to pending SIGALRM, there is a similar
problem with pending SIGIO from the keyboard driver during core dump.

Signed-off-by: Rami Ylimaki <ext-rami.ylimaki at nokia.com>
---
 composite/compwindow.c          |    2 +-
 glx/glthread.c                  |    2 +-
 hw/dmx/examples/xinput.c        |    2 +-
 hw/kdrive/src/kdrive.c          |    2 +-
 hw/xfree86/common/xf86Init.c    |    2 +-
 hw/xquartz/GL/capabilities.c    |    2 +-
 miext/damage/damage.c           |   10 +++++-----
 miext/rootless/rootlessWindow.c |    2 +-
 os/log.c                        |    4 ++--
 9 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/composite/compwindow.c b/composite/compwindow.c
index c10cb9e..8c2c9bd 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -205,7 +205,7 @@ compPositionWindow (WindowPtr pWin, int x, int y)
 #ifdef COMPOSITE_DEBUG
     if ((pWin->redirectDraw != RedirectDrawNone) !=
 	(pWin->viewable && (GetCompWindow(pWin) != NULL)))
-	abort ();
+	OsAbort (TRUE);
 #endif
     if (pWin->redirectDraw != RedirectDrawNone)
     {
diff --git a/glx/glthread.c b/glx/glthread.c
index 4caaea1..57c3750 100644
--- a/glx/glthread.c
+++ b/glx/glthread.c
@@ -129,7 +129,7 @@ _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
 _X_EXPORT unsigned long
 _glthread_GetID(void)
 {
-   abort();   /* XXX not implemented yet */
+   OsAbort(TRUE);   /* XXX not implemented yet */
    return (unsigned long) 0;
 }
 
diff --git a/hw/dmx/examples/xinput.c b/hw/dmx/examples/xinput.c
index 74353a9..053f864 100644
--- a/hw/dmx/examples/xinput.c
+++ b/hw/dmx/examples/xinput.c
@@ -233,7 +233,7 @@ int main(int argc, char **argv)
         int         total = 0;
 
 #define ADD(type)                                     \
-        if (cnt >= MAX_EVENTS) abort();               \
+        if (cnt >= MAX_EVENTS) OsAbort(TRUE);         \
         names[cnt] = #type;                           \
         type(dev, event_type[cnt], event_list[cnt]);  \
         if (event_type[cnt]) ++cnt
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 7675c1e..59592fe 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -335,7 +335,7 @@ AbortDDX(void)
     }
 
     if (kdCaughtSignal)
-        abort();
+        OsAbort(TRUE);
 }
 
 void
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 6707448..7df1628 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -1225,7 +1225,7 @@ ddxGiveUp(void)
 
     /* If an unexpected signal was caught, dump a core for debugging */
     if (xf86Info.caughtSignal)
-	abort();
+	OsAbort(TRUE);
 }
 
 
diff --git a/hw/xquartz/GL/capabilities.c b/hw/xquartz/GL/capabilities.c
index 4306404..0bad900 100644
--- a/hw/xquartz/GL/capabilities.c
+++ b/hw/xquartz/GL/capabilities.c
@@ -522,7 +522,7 @@ bool getGlCapabilities(struct glCapabilities *cap) {
 	    conf = malloc(sizeof(*conf));
 	    if(NULL == conf) {
             perror("malloc");
-            abort();
+            OsAbort(TRUE);
 	    }
 
 	    /* Copy the struct. */
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index b7ec92a..c194d77 100644
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -1705,7 +1705,7 @@ damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
     }
 #if DAMAGE_VALIDATE_ENABLE
     ErrorF ("Damage not on list\n");
-    abort ();
+    OsAbort (TRUE);
 #endif
 }
 
@@ -1718,7 +1718,7 @@ damageInsertDamage (DamagePtr *pPrev, DamagePtr pDamage)
     for (pOld = *pPrev; pOld; pOld = pOld->pNext)
 	if (pOld == pDamage) {
 	    ErrorF ("Damage already on list\n");
-	    abort ();
+	    OsAbort (TRUE);
 	}
 #endif
     pDamage->pNext = *pPrev;
@@ -1971,7 +1971,7 @@ DamageRegister (DrawablePtr pDrawable,
     if (pDrawable->pScreen != pDamage->pScreen)
     {
 	ErrorF ("DamageRegister called with mismatched screens\n");
-	abort ();
+	OsAbort (TRUE);
     }
 #endif
 
@@ -1986,7 +1986,7 @@ DamageRegister (DrawablePtr pDrawable,
 	for (pOld = *pPrev; pOld; pOld = pOld->pNextWin)
 	    if (pOld == pDamage) {
 		ErrorF ("Damage already on window list\n");
-		abort ();
+		OsAbort (TRUE);
 	    }
 #endif
 	pDamage->pNextWin = *pPrev;
@@ -2040,7 +2040,7 @@ DamageUnregister (DrawablePtr	    pDrawable,
 #if DAMAGE_VALIDATE_ENABLE
 	if (!found) {
 	    ErrorF ("Damage not on window list\n");
-	    abort ();
+	    OsAbort (TRUE);
 	}
 #endif
     }
diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c
index 5320956..19b9cc1 100644
--- a/miext/rootless/rootlessWindow.c
+++ b/miext/rootless/rootlessWindow.c
@@ -978,7 +978,7 @@ StartFrameResize(WindowPtr pWin, Bool gravity,
                 copy_rect.y2 = oldY2;
             }
             else
-                abort();
+                OsAbort(TRUE);
 
             Bpp = winRec->win->drawable.bitsPerPixel / 8;
             copy_rect_width = copy_rect.x2 - copy_rect.x1;
diff --git a/os/log.c b/os/log.c
index 08fa1f2..cfe81a9 100644
--- a/os/log.c
+++ b/os/log.c
@@ -404,7 +404,7 @@ AbortServer(void)
     AbortDDX();
     fflush(stderr);
     if (CoreDump)
-	abort();
+	OsAbort(TRUE);
     exit (1);
 }
 
@@ -528,7 +528,7 @@ FatalError(const char *f, ...)
 	beenhere = TRUE;
 	AbortServer();
     } else
-	abort();
+	OsAbort(TRUE);
     /*NOTREACHED*/
 }
 
-- 
1.6.0.4



More information about the xorg-devel mailing list