"gs -dNODISPLAY" crashes on HP-UX v. 11.23 for Itanium provided by HP test drive. GS 8.14 crashes too. HP compiler generates many nasty warnings. HP-UX spe176 B.11.23 U ia64 1858530828 unlimited-user license aC++/C Version A.05.55.02
Created attachment 877 [details] 2.txt stderr messages
The bug happens when ARCH_ALIGN_STRUCT_MOD==16 and sizeod(ref)==8 and can be reproduced on PC by editing arch.h Disabling of the special cased (or fixing them) helps somewhat bit it is not the only bug. Index: gs/src/ialloc.c =================================================================== RCS file: /cvs/ghostscript/gs/src/ialloc.c,v retrieving revision 1.7 diff -b -u -r1.7 ialloc.c --- gs/src/ialloc.c 4 Aug 2004 19:36:12 -0000 1.7 +++ gs/src/ialloc.c 8 Sep 2004 11:54:00 -0000 @@ -157,7 +157,7 @@ /* If we're allocating a run of refs already, */ /* and we aren't about to overflow the maximum run length, use it. */ - if (mem->cc.rtop == mem->cc.cbot && + if (mem->cc.rtop == mem->cc.cbot && false && num_refs < (mem->cc.ctop - mem->cc.cbot) / sizeof(ref) && mem->cc.rtop - (byte *) mem->cc.rcur + num_refs * sizeof(ref) < max_size_st_refs @@ -225,7 +225,7 @@ return_error(e_Fatal); diff = old_num_refs - new_num_refs; /* Check for LIFO. See gs_free_ref_array for more details. */ - if (mem->cc.rtop == mem->cc.cbot && + if (mem->cc.rtop == mem->cc.cbot && false && (byte *) (obj + (old_num_refs + 1)) == mem->cc.rtop ) { /* Shorten the refs object. */ @@ -262,7 +262,7 @@ * for the moment, if it's anything but a t_array, punt. * The +1s are for the extra ref for the GC. */ - if (!r_has_type(parr, t_array)) + if (!r_has_type(parr, t_array) || true) DO_NOTHING; /* don't look for special cases */ else if (mem->cc.rtop == mem->cc.cbot && (byte *) (obj + (num_refs + 1)) == mem->cc.rtop
please go ahead and track this one down.
The fix is submitted to code review: http://ghostscript.com/pipermail/gs-code-review/2004-September/004617.html
*** Bug 687730 has been marked as a duplicate of this bug. ***
We looked at this bug again during our support call today. Raph will attempt to review, but this is too scary to go in for 8.50. Presumedly there is a work around, since sizeof(ref)==8 implies 32 bit pointers; one expects this is from a 'broken ptr=int' workaround mode in the compiler and can be switched off in the compiler.
The structure alignment requirement comes from the alignment of jmp_buf, which may be a hardware constrain. See genarch.c . Does the compilation in LP64 model qualifies as a work-around ? How about issuing #error on the platforms where GS is broken ? Regarding the scary fix, the fix can be tested on the available platforms by modifying arch.h . When the ref's are mishandled, GS fails during start-up. With the proposed fix GS completes the regression test.
Re-assigning to Raph, who has a fix. Raph: prehaps you could attach your patch here for Luca to verify in the meantime?
Raph's patch is not attached. Here's another approach to the problem that can be quickly developed into a working patch. Since we control all calls to setjmp()/lobgjmp() in Ghostscript we can drop the requirement that memory is aligned to ARCH_ALIGN_STRUCT_MOD and deal with unaligned jmp_buf; /* define a type with some slack at the end */ typedef struct tag_jmp_buf_padded { jmp_buf buf; char[8] pad; } jmp_buf_padded[1]; int setjmp_unaligned(jmp_buf_padded env) { if (aligned(env) ) { return setjmp(env.buf); } else { int i=setjmp((jmp_buf)((char *)env+8)); memmove((char *)(env.buf)+8, env.buf, sizeof(env.buf)); return i; } } void longjmp_unaligned( jmp_buf_padded env, int value ) { if (aligned(env)) { longjmp(env.buf); } else { memmove(env.buf, (char *)(env+8), sizeof(jmp_buf)); longjmp((jmp_buf)((char *)env)+8), value); } }
Raph, where's your fix? Here's a new link to the old patch. Is it still scaly ? http://ghostscript.com/pipermail/gs-code-review/2004-September/004649.html Does anybody want to comment on the work-around that deals with misaligned mp_buf ?
Received from ian@davenant.greenend.org.uk http://bugs.ghostscript.com/show_bug.cgi?id=687643 describes a problem where gs makes an unjustified assumption about the relative sizes and alignments of ref and jmp_buf. Sorry to emailing you. I would have submitted my comments to the Bugzilla but the account creation email never arrived. (In any case, I think having to create an account to make my contribution is very silly and will discourage many people!) Also, I couldn't find _any_ email address for upstream gs in the gs-esp 7.07.1 package ! So I hope that any of you who receive this and are in, or know how to contact, the GPL or Aladdin gs team will pass this on. At the bottom of the bugzilla entry, Alex Cherepanov suggests a workaround involving faking up a version of setjmp et al that don't have the 16-byte alignment requirement. I have implemented this suggestion and attach a patch. I made the (I hope not unjustified) assumption that gs does not memcpy its jmp_bufs about. Thank you for your attention. Regards, Ian. diff -x '*~' -ruN ../orig/gs-esp-7.07.1/debian/changelog gs-esp-7.07.1/debian/changelog --- ../orig/gs-esp-7.07.1/debian/changelog 2005-08-30 18:56:12.000000000 +0100 +++ gs-esp-7.07.1/debian/changelog 2005-08-30 18:55:44.000000000 +0100 @@ -1,3 +1,30 @@ +gs-esp (7.07.1-9ubuntu5) breezy; urgency=low + + * Fix coredumping bug on ppc: Ubuntu bugzilla: + http://bugzilla.ubuntu.com/show_bug.cgi?id=13771 + This is the same issue as + http://bugs.ghostscript.com/show_bug.cgi?id=687643 + http://bugs.ghostscript.com/show_bug.cgi?id=687730 + discussed in + http://ghostscript.com/pipermail/gs-code-review/2004-September/004649.html + and probably the same as Debian bug #324796 and perhaps others in + Debian's gs-esp. + + This bug is due to gs's incorrect assumption that (where ref is an + important struct inside gs) sizeof(ref) % alignof(jmp_buf) == 0. This + is not true on ppc and apparently not necessarily on Itanium either. + + The `fix' I have applied is to wrap setjmp/longjmp up in macros which + arrange for jmp_buf to have alignment 1, as sketched out in the URLs + above. A previous attempt to fix it by padding ref out to the + alignment of jmp_buf failed and I don't know why; but I suspect other + unjustified assumptions in gs. + + GhostScript's algorithms ought to be repaired not to assume + falsehoods. + + -- Ian Jackson <ian@davenant.greenend.org.uk> Tue, 30 Aug 2005 18:55:44 +0100 + gs-esp (7.07.1-9ubuntu4) breezy; urgency=low * Rebuild for new C++ ABI diff -x '*~' -ruN ../orig/gs-esp-7.07.1/src/genarch.c gs-esp-7.07.1/src/genarch.c --- ../orig/gs-esp-7.07.1/src/genarch.c 2003-08-19 16:32:25.000000000 +0100 +++ gs-esp-7.07.1/src/genarch.c 2005-08-30 18:46:40.000000000 +0100 @@ -28,7 +28,8 @@ */ #include <string.h> #include <time.h> -#include <setjmp.h> + +#include "gsfix-setjmp.h" /* We should write the result on stdout, but the original Turbo C 'make' */ /* can't handle output redirection (sigh). */ diff -x '*~' -ruN ../orig/gs-esp-7.07.1/src/gp_os2.c gs-esp-7.07.1/src/gp_os2.c --- ../orig/gs-esp-7.07.1/src/gp_os2.c 2003-07-13 05:43:17.000000000 +0100 +++ gs-esp-7.07.1/src/gp_os2.c 2005-08-30 18:46:40.000000000 +0100 @@ -72,7 +72,7 @@ #ifdef __DLL__ /* use longjmp instead of exit when using DLL */ -#include <setjmp.h> +#include "gsfix-setjmp.h" extern jmp_buf gsdll_env; #endif diff -x '*~' -ruN ../orig/gs-esp-7.07.1/src/gsfix-setjmp.h gs-esp-7.07.1/src/gsfix-setjmp.h --- ../orig/gs-esp-7.07.1/src/gsfix-setjmp.h 1970-01-01 01:00:00.000000000 +0100 +++ gs-esp-7.07.1/src/gsfix-setjmp.h 2005-08-30 18:46:40.000000000 +0100 @@ -0,0 +1,35 @@ +#ifndef GSFIX_SETJMP_H +#define GSFIX_SETJMP_H + +#include <setjmp.h> + +typedef struct { + char c; + jmp_buf j; +} gsfix_jmp_buf_test; + +#define gsfix_jmp_buf_align ((size_t)&((gsfix_jmp_buf_test*)0)->j) + +typedef struct { + unsigned char stuff[sizeof(jmp_buf) + gsfix_jmp_buf_align]; +} gsfix_jmp_buf; + +#define gsfix_orig_jmp_buf jmp_buf +#define gsfix_orig_setjmp(x) setjmp(x) +#define gsfix_orig_longjmp(x,y) longjmp((x),(y)) + +#undef jmp_buf +#undef setjmp +#undef longjmp + +#define jmp_buf gsfix_jmp_buf +#define setjmp(x) (gsfix_orig_setjmp(find_jmp_buf((x)))) +#define longjmp(x,val) (gsfix_orig_longjmp(find_jmp_buf((x)),(val))) + +#define find_jmp_buf(gsfjb) \ + ( \ + ((size_t)(gsfjb).stuff + gsfix_jmp_buf_align) \ + & ~(size_t)(gsfix_jmp_buf_align-1) \ + ) + +#endif /*GSFIX_SETJMP_H*/ diff -x '*~' -ruN ../orig/gs-esp-7.07.1/src/sdct.h gs-esp-7.07.1/src/sdct.h --- ../orig/gs-esp-7.07.1/src/sdct.h 2002-04-23 12:58:47.000000000 +0100 +++ gs-esp-7.07.1/src/sdct.h 2005-08-30 18:46:40.000000000 +0100 @@ -21,7 +21,7 @@ #ifndef sdct_INCLUDED # define sdct_INCLUDED -#include <setjmp.h> /* for jmp_buf */ +#include "gsfix-setjmp.h" /* for jmp_buf */ /* ------ DCT filters ------ */
The URL in Comment #4 now can't resolve. The thing in Comment #10 won't work - can't use setjmp in a function, which is not on stack. The thing in Comment #12 probably can work (I was not much attentive), but introducing new macros to be decided by Raph.
The new URL of the patch #4 is in the comment #11.
*** Bug 688329 has been marked as a duplicate of this bug. ***
Changing severity to 'blocker' to identify this as something we want fixed before the 8.54 release.
A patch similar to #12, but without using macros to redefine the setjmp identifiers, was committed as svn revision 6748: http://ghostscript.com/pipermail/gs-cvs/2006-May/006508.html
gs -dNODISPLAY still segfaults for me on PPC linux with 8.54rc2 and trunk r6763.
it looks like the value of ARCH_ALIGN_STRUCT_MOD has not been changed in the proposed patch.
Created attachment 2198 [details] Patch for the memory alignment. The previous patch implemented the jmp_buf adjustments bud didn't change the memory alignment that caused the crash. Log message: Some architectures have special alignment requirements for jmp_buf, but we've dropped them in favor of sizeof(ref) % obj_align_mod == 0 assumed thtoughout te gs code and align jmp_buf by hand in setjmp_.h . Testing now.
Created attachment 2199 [details] updated patch removing ARCH_ALIGN_JMP_BUF_MOD I've confirmed Alex's patch fixes the issue on PPC Linux. Attaching a modified version with a better comment and removing ARCH_ALIGN_JMP_BUF_MOD entirely.
This commit should finally resolve the bug. http://ghostscript.com/pipermail/gs-cvs/2006-May/006532.html