Sylvain,
I did some more investigation.
>>>>> SM == Sylvain Mazet writes:
SM> Now I just try to understand how
SM> unsigned char "type"
SM> can work on other platforms.
SM>
SM> with unsigned char "type":
SM> Rune->cursor_type offset 16
SM> Rune->type offset 17
SM> Rune->object offset 20
SM> sizeof(Rune) = 44
SM>
SM> My guess is:
SM>
SM> * (int*) (&Rune->type)
SM>
SM> in lispdesc_indirect_count_1
SM> works on other platforms because all of these:
SM>
SM> - bytes 18-19 of rune are zero.
Thats correct, memory is zeroed at allocation time.
SM> - first byte of "object" member must also be zero (this I dont get).
No it is not. And this leads to an uncorrent count value!
The data looks like this:
offset 16: 1 (the value as it is meant)
offset 17: 0
offset 18: 0
offset 19: 10 (this is the first byte of "object")
In binary this is:
(gdb) x/t irdata
0x8b63885: 00001010000000000000000000000001
Altogether on a little endian machine leads to an int value (offset 16--19):
* (int*) (&Rune->type) ==> 167772161
Later in lispdesc_process_xd_union this wrong count value randomly leads to
the correct result: no variant of the XD_UNION is matched, so nothing is
marked. In this case this is correct, since variant 1 only contains a char,
so this variant has not to be processed.
This should break for variant 2, which contains Lisp_Objects that have to be
marked. Those wouldn't get marked then (at least not through this branch of
the mark tree). Anyways, I couldn't produce this situation, maybe they get
marked by another branch.
So this really is a bug on _all_ systems, not only on sparc.
I don't know why this causes a crash on sparc. Maybe it has problems with
the not aligned integer cast. But this is just a guess. Anyways, it is good
that it did!
SM> - system has to be little endian? (sparc is big endian)
SM>
SM> PS: with unsigned int type, "type" gets aligned:
SM> Rune->cursor_type offset 16
SM> Rune->type offset 20
SM> Rune->object offset 24
SM> sizeof(Rune) = 48
Well, I think this is the tradeoff we have to make here. The struct rune is
going to be 4 bytes bigger than before.
Yesterday I forgot to add a changelog entry to my patch, so here it is
again, this time complete:
src/ChangeLog addition:
2005-03-02 Marcus Crestani <crestani(a)informatik.uni-tuebingen.de>
* redisplay.h (struct rune): make type field an int, to fix
KKCC marking of unions.
xemacs-21.5 source patch:
Diff command: cvs -q diff -u
Files affected: src/redisplay.h
Index: src/redisplay.h
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/redisplay.h,v
retrieving revision 1.22
diff -u -r1.22 redisplay.h
--- src/redisplay.h 26 Jan 2005 10:33:42 -0000 1.22
+++ src/redisplay.h 3 Mar 2005 00:46:19 -0000
@@ -144,7 +144,7 @@
unsigned char cursor_type; /* is this rune covered by the cursor? */
- unsigned char type; /* type of rune object */
+ unsigned int type; /* type of rune object */
/* We used to do bitfields here, but if I
(JV) count correctly that doesn't matter
for the size of the structure. All the
bit
--
Marcus
P.S.: Sylvain, please keep the discussion on the list.