os: Prevent core dump from being truncated.

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@nokia.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Rami Ylimaki 2010-01-28 11:08:34 +02:00 committed by Keith Packard
parent ca364ca82a
commit 5b9a52be7e
9 changed files with 14 additions and 14 deletions

View File

@ -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 ();
#endif
if (pWin->redirectDraw != RedirectDrawNone)
{

View File

@ -129,7 +129,7 @@ _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
_X_EXPORT unsigned long
_glthread_GetID(void)
{
abort(); /* XXX not implemented yet */
OsAbort(); /* XXX not implemented yet */
return (unsigned long) 0;
}

View File

@ -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(); \
names[cnt] = #type; \
type(dev, event_type[cnt], event_list[cnt]); \
if (event_type[cnt]) ++cnt

View File

@ -335,7 +335,7 @@ AbortDDX(void)
}
if (kdCaughtSignal)
abort();
OsAbort();
}
void

View File

@ -1235,7 +1235,7 @@ ddxGiveUp(void)
/* If an unexpected signal was caught, dump a core for debugging */
if (xf86Info.caughtSignal)
abort();
OsAbort();
}

View File

@ -522,7 +522,7 @@ bool getGlCapabilities(struct glCapabilities *cap) {
conf = malloc(sizeof(*conf));
if(NULL == conf) {
perror("malloc");
abort();
OsAbort();
}
/* Copy the struct. */

View File

@ -1705,7 +1705,7 @@ damageRemoveDamage (DamagePtr *pPrev, DamagePtr pDamage)
}
#if DAMAGE_VALIDATE_ENABLE
ErrorF ("Damage not on list\n");
abort ();
OsAbort ();
#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 ();
}
#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 ();
}
#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 ();
}
#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 ();
}
#endif
}

View File

@ -978,7 +978,7 @@ StartFrameResize(WindowPtr pWin, Bool gravity,
copy_rect.y2 = oldY2;
}
else
abort();
OsAbort();
Bpp = winRec->win->drawable.bitsPerPixel / 8;
copy_rect_width = copy_rect.x2 - copy_rect.x1;

View File

@ -413,7 +413,7 @@ AbortServer(void)
AbortDDX();
fflush(stderr);
if (CoreDump)
abort();
OsAbort();
exit (1);
}
@ -537,7 +537,7 @@ FatalError(const char *f, ...)
beenhere = TRUE;
AbortServer();
} else
abort();
OsAbort();
/*NOTREACHED*/
}