[elinks-users] crash on 64bit archs

Jonas Fonseca fonseca at diku.dk
Tue May 10 16:22:47 PDT 2005


Karel Zak <kzak at redhat.com> wrote Mon, May 09, 2005:
> On Sat, 2005-05-07 at 01:58 +0200, Jonas Fonseca wrote:
> > Karel Zak <kzak at redhat.com> wrote Thu, May 05, 2005:
> > > 
> > > It looks that Elinks is useless on 64bit archs. I tested 0.10.3 and
> > > 0.10.5 on ppc and ia64.
> > 
> > It could be some code in the URI comparing or URI parsing which tries to
> > be too smart and 32-bit friendly. I will try to find my way to a 64-bit
> > system at school.
> > 
> > In the meantime, maybe you could give us a real backtrace dump from gdb
> > instead of the less readable crash backtrace?
> 
> 
> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=156647

Thanks for posting this.

> Generally, if something works with -O0 and does not with -O2, it is more often
> an application bug than GCC bug.  Only when you debug it and prove it is indeed
> a GCC bug it should be reassigned to GCC.
> 
> Particularly in this case, the bug goes away with -O2 -fno-strict-aliasing,
> and there are 94 places where GCC warns about aliasing problems:

The bug would probably also go away if

	#define do_not_optimize_here_gcc_4_x(x) do_not_optimize_here(x)

macros was introduced and used where the ones for gcc_3_x is today.

> And error.h even shows that the authors see the problems, just for unknown
> reason can't admit it is their bug and not a compiler bug:

Maybe you are right but if it gets the work done and makes it possible
to focus on more important issues. ;-)

> The lists implementation is broken by design, it just can't work that way.
> You can't access the same object through aliasing incompatible types.
> But lists.h is doing that a lot, it sometimes accesses next/prev as void *,
> sometimes as struct cache_entry *, etc.

Why is that a problem when the access is not through a variable local to
the list operation? Usually the access is done by casting the pointer.

(I admit I am only starting to really understand the problem.)

> Cleanest fix IMHO would be to use a void *next; void *prev; structure and
> put that structure as first field into the various structures that are chained
> into lists, say:
> 
> struct cache_entry
> {
>   struct list_head_elinks head;
>   ...
> }
> 
> and then the macro use cached->head.prev, etc.  What will also work
> is just make the prev/next pointers void *, but directly in the structure, say
> 
> struct cache_entry
> {
>   void *next; void *prev;
>   ...
> }
> 
> and have
> 
> struct list_head_elinks
> {
>   void *next; void *prev;
> };

Yes, I have probed some of those but won't promise anything, unless
somebody else comes up with a clean patch/way to do it.

BTW, would the following be acceptable too?

#define foreach(e,l) \
	for ((e) = (void *) (l).next); \
	     (e) != (void *) &(l); \
	     (e) = (e)->next);

Note, e might have type struct cache_entry *.

It removes some of the warnings and is less intrusive.

> But writing/reading through void ** pointer and then writing/reading through
> struct cache_entry ** pointer is violation of ISO C99 6.5 (6,7).

Where in the ELinks code is this ever the case?

-- 
Jonas Fonseca



More information about the elinks-users mailing list