ALLOCATE_LOCAL / crashes
So, it seems that ALLOCATE_LOCAL is responsible for at least some of the "rootless crashes" we're seeing -- specifically, all of the ones where the crash fell in any of the mi* functions. (My understanding is that ALLOCATE_LOCAL is more dangerous to use on Leopard due to virtual memory layout -- it should never be used to allocate more than about a kilobyte, and I just saw miFillPolyArc crash by trying to allocate 900k.) http://gitweb.freedesktop.org/?p=xorg/xserver.git;a=commit;h=7caf51d1a5a86ae... -- Ben Byer CoreOS / BSD Technology Group, XDarwin maintainer
On Dec 6, 2007, at 9:07 PM, Ben Byer wrote:
So, it seems that ALLOCATE_LOCAL is responsible for at least some of the "rootless crashes" we're seeing -- specifically, all of the ones where the crash fell in any of the mi* functions.
(My understanding is that ALLOCATE_LOCAL is more dangerous to use on Leopard due to virtual memory layout -- it should never be used to allocate more than about a kilobyte, and I just saw miFillPolyArc crash by trying to allocate 900k.)
http://gitweb.freedesktop.org/?p=xorg/xserver.git;a=commit;h=7caf51d1a5a86ae...
ALLOCATE_LOCAL has caused trouble since XDarwin's earliest days. (Symptom then: remotely run Solaris Netscape on some golfing web page, then select all. Crash while filling some very large number of rectangles.) The problem can be simple stack overflow, or exceeding the maximum single stack frame. (The latter may only be a problem on ppc with old versions of gcc.) I see that the Xserver thread is using the default pthread stack size, only 500K. Boosting that to 8MB (matching the stack size for the main thread) would help, but you'll still probably have pathological cases. Linux gets to grow its stack until it runs into some other allocation, so it can cope better with alloca(bignum). Still, 900KB? How big of an arc was it trying to draw? -- Greg Parker gparker@apple.com Runtime Wrangler
ALLOCATE_LOCAL has caused trouble since XDarwin's earliest days. (Symptom then: remotely run Solaris Netscape on some golfing web page, then select all. Crash while filling some very large number of rectangles.) The problem can be simple stack overflow, or exceeding the maximum single stack frame. (The latter may only be a problem on ppc with old versions of gcc.)
I see that the Xserver thread is using the default pthread stack size, only 500K. Boosting that to 8MB (matching the stack size for the main thread) would help, but you'll still probably have pathological cases. Linux gets to grow its stack until it runs into some other allocation, so it can cope better with alloca(bignum).
Eh, well... that digging was sure quick... Thanks Greg =)
Still, 900KB? How big of an arc was it trying to draw?
Keep in mind, this might just be the straw that broke the camel's back. We might have some alloc(big) lower in the stack.
I saw in some post somewhere that alloca() was known to cause X to crash on darwin for some reason. I can't remember where, but I'll try to figure out where I saw that and why. --Jeremy On Dec 6, 2007, at 21:07, Ben Byer wrote:
So, it seems that ALLOCATE_LOCAL is responsible for at least some of the "rootless crashes" we're seeing -- specifically, all of the ones where the crash fell in any of the mi* functions.
(My understanding is that ALLOCATE_LOCAL is more dangerous to use on Leopard due to virtual memory layout -- it should never be used to allocate more than about a kilobyte, and I just saw miFillPolyArc crash by trying to allocate 900k.)
http://gitweb.freedesktop.org/?p=xorg/xserver.git;a=commit;h=7caf51d1a5a86ae...
-- Ben Byer CoreOS / BSD Technology Group, XDarwin maintainer
_______________________________________________ Xquartz-dev mailing list Xquartz-dev@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo/xquartz-dev
So... I wonder if we should do this across the board when compiling X. Other things than the server use Xalloca.h. I'm thinking I should put it in my standard CFLAGS. Am I being overly cautious and paranoid, or is that something worth doing? --Jeremy On Dec 6, 2007, at 21:07, Ben Byer wrote:
So, it seems that ALLOCATE_LOCAL is responsible for at least some of the "rootless crashes" we're seeing -- specifically, all of the ones where the crash fell in any of the mi* functions.
(My understanding is that ALLOCATE_LOCAL is more dangerous to use on Leopard due to virtual memory layout -- it should never be used to allocate more than about a kilobyte, and I just saw miFillPolyArc crash by trying to allocate 900k.)
http://gitweb.freedesktop.org/?p=xorg/xserver.git;a=commit;h=7caf51d1a5a86ae...
-- Ben Byer CoreOS / BSD Technology Group, XDarwin maintainer
_______________________________________________ Xquartz-dev mailing list Xquartz-dev@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo/xquartz-dev
On Dec 7, 2007, at 1:48 PM, Jeremy Huddleston wrote:
So... I wonder if we should do this across the board when compiling X. Other things than the server use Xalloca.h. I'm thinking I should put it in my standard CFLAGS. Am I being overly cautious and paranoid, or is that something worth doing?
We should do something like this. It uses alloca() if the allocation is small enough, otherwise it uses the fallback allocator (probably malloc or Xalloc). The start of the block holds the allocated size so DEALLOCATE_LOCAL knows whether to call free. (16KB might be too small on i386 and/or too big on ppc. There's lots of gcc-isms here; it should be protected by __GNUC__ or something. I think it works in C++ too. I have only tested it trivially.) #ifndef ALLOCATE_LOCAL_MAX_ALLOCA #define ALLOCATE_LOCAL_MAX_ALLOCA (16*1024) #endif #define ALLOCATE_LOCAL(size) \ ({ \ __SIZE_TYPE__ _x_size = \ sizeof(__SIZE_TYPE__) + (__SIZE_TYPE__) (size); \ __SIZE_TYPE__ *_x_p; \ if (_x_size > ALLOCATE_LOCAL_MAX_ALLOCA) { \ _x_p = (__SIZE_TYPE__ *)ALLOCATE_LOCAL_FALLBACK(_x_size); \ } else { \ _x_p = (__SIZE_TYPE__ *)__builtin_alloca(_x_size); \ } \ if (_x_p) *_x_p = _x_size; \ (void *)(_x_p + 1); \ }) #define DEALLOCATE_LOCAL(ptr) \ ({ \ __SIZE_TYPE__ *_x_p = (__SIZE_TYPE__ *)(ptr); \ if (_x_p) { \ _x_p = _x_p - 1; \ __SIZE_TYPE__ _x_size = *_x_p; \ if (_x_size > ALLOCATE_LOCAL_MAX_ALLOCA) { \ DEALLOCATE_LOCAL_FALLBACK(_x_p); \ } \ } \ }) -- Greg Parker gparker@apple.com Runtime Wrangler
Hi Keith, We've been having some trouble due to alloca(BIG) in the Xquartz server. Could you comment on the acceptability of something like Greg suggests below? Should we put it inside __APPLE__ ifdefs, or do you think it would be good across the board? Or do you have a better solution we should think about? Thanks, Jeremy Begin forwarded message: From: Greg Parker <gparker@apple.com> Date: December 7, 2007 15:27:17 PST To: Developer talk about Xquartz <xquartz-dev@lists.macosforge.org> Subject: Re: [Xquartz-dev] ALLOCATE_LOCAL / crashes Reply-To: Developer talk about Xquartz <xquartz- dev@lists.macosforge.org> On Dec 7, 2007, at 1:48 PM, Jeremy Huddleston wrote:
So... I wonder if we should do this across the board when compiling X. Other things than the server use Xalloca.h. I'm thinking I should put it in my standard CFLAGS. Am I being overly cautious and paranoid, or is that something worth doing?
We should do something like this. It uses alloca() if the allocation is small enough, otherwise it uses the fallback allocator (probably malloc or Xalloc). The start of the block holds the allocated size so DEALLOCATE_LOCAL knows whether to call free. (16KB might be too small on i386 and/or too big on ppc. There's lots of gcc-isms here; it should be protected by __GNUC__ or something. I think it works in C++ too. I have only tested it trivially.) #ifndef ALLOCATE_LOCAL_MAX_ALLOCA #define ALLOCATE_LOCAL_MAX_ALLOCA (16*1024) #endif #define ALLOCATE_LOCAL(size) \ ({ \ __SIZE_TYPE__ _x_size = \ sizeof(__SIZE_TYPE__) + (__SIZE_TYPE__) (size); \ __SIZE_TYPE__ *_x_p; \ if (_x_size > ALLOCATE_LOCAL_MAX_ALLOCA) { \ _x_p = (__SIZE_TYPE__ *)ALLOCATE_LOCAL_FALLBACK(_x_size); \ } else { \ _x_p = (__SIZE_TYPE__ *)__builtin_alloca(_x_size); \ } \ if (_x_p) *_x_p = _x_size; \ (void *)(_x_p + 1); \ }) #define DEALLOCATE_LOCAL(ptr) \ ({ \ __SIZE_TYPE__ *_x_p = (__SIZE_TYPE__ *)(ptr); \ if (_x_p) { \ _x_p = _x_p - 1; \ __SIZE_TYPE__ _x_size = *_x_p; \ if (_x_size > ALLOCATE_LOCAL_MAX_ALLOCA) { \ DEALLOCATE_LOCAL_FALLBACK(_x_p); \ } \ } \ }) -- Greg Parker gparker@apple.com Runtime Wrangler _______________________________________________ Xquartz-dev mailing list Xquartz-dev@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo/xquartz-dev
On Sat, 2007-12-08 at 12:29 -0800, Jeremy Huddleston wrote:
Hi Keith,
We've been having some trouble due to alloca(BIG) in the Xquartz server. Could you comment on the acceptability of something like Greg suggests below? Should we put it inside __APPLE__ ifdefs, or do you think it would be good across the board? Or do you have a better solution we should think about?
Master has removed alloca for the X server -- it's insecure, and prone to failure. Just use malloc. -- keith.packard@intel.com
participants (5)
-
Ben Byer
-
Greg Parker
-
Jeremy Huddleston
-
Jeremy Huddleston
-
Keith Packard