discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: problem with gnustep on OpenBSD sparc64


From: Sebastian Reitenbach
Subject: Re: problem with gnustep on OpenBSD sparc64
Date: Thu, 07 Jul 2011 10:01:24 +0200
User-agent: SOGoMail 1.3.7

Hi,
 
On Wednesday, July 6, 2011 20:50 CEST, David Chisnall <theraven@sucs.org> 
wrote: 
 
> On 6 Jul 2011, at 19:35, Sebastian Reitenbach wrote:
> 
> > 
> > On Wednesday, July 6, 2011 19:47 CEST, David Chisnall <theraven@sucs.org> 
> > wrote: 
> > 
> >> The stuff around skip type qualifiers is irrelevant - there aren't any, 
> >> this function is a no-op in this case, ignore it.
> >> 
> >> 
> >> On 6 Jul 2011, at 18:38, Sebastian Reitenbach wrote:
> >> 
> >>> I added some more fprintf's to the functions that are involved, hope the 
> >>> output also helps:
> >>> $ ./a.out      
> >>> parse_array: element_count: 3, type: [4i]]
> >>> parse_array: element_count: 4, type: i]]
> >> 
> >> 
> >> Well, this shows that it is finding the correct number of elements for 
> >> each array.  So, there are two places where it could be going wrong:
> >> 
> >> - Calculating the size of int (line 161)
> > I added two fprintfs before and after that line
> > 
> >> - Combining the size of the elements with the count (line 197)
> > and another fprintf before that line, after the parse_array:
> > 
> > and another 2 fprintf in parse_array, before and after calling the callback.
> > 
> > $ ./a.out  
> > parse_array: type: [4i]]
> > parse_array: type: i]]
> > ^^^ those lines are in parse_array before the callback
> 
> That's good.  The elements of the outer array are of type [4i], the elements 
> of the inner array are of type i.
> 
> > sizeof_type: sizeof(typeName): 4
> > sizeof_type: size: 32
> > ^^^ those lines are around line 161
> 
> int is 32 bits, that looks sensible.  The size of the inner array is 32 bits 
> (note: we work with bits internally because this code needs to handle 
> bitfields, which are ugly and evil).
> 
> > parse_array: type: ]]
> > ^^^ fprintf after calling callback
> 
> Okay, now it's coming back up.  
> 
> > element_size: 0, element_count: 4
> > ^^^ this line is before line 197
> 
> Hmm, why is element_size 0 here?  It was 32 just now - somehow it got reset 
> to 0.  This looks like the bug. element_size should have been set to 32 on 
> line 161.  Can you check that the address of element_size passed in here is 
> the same as the address of size on line 161?

I extended the output a bit, to show the address used for size (a.k.a. context 
in parse_array)

$ ./a.out  
sizeof_type: before calling parse_array: element_size: 0, size pointern: 
0xfffffffffffcf260
parse_array: type: [4i]], context a.k.a. size: 0xfffffffffffcf260
sizeof_type: before calling parse_array: element_size: 0, size pointern: 
0xfffffffffffcf0d0
parse_array: type: i]], context a.k.a. size: 0xfffffffffffcf0d0
sizeof_type: sizeof(typeName): 4 size pointer: 0xfffffffffffcf0d0
sizeof_type: size: 32, size pointer: 0xfffffffffffcf0d0
parse_array: type: ]]
sizeof_type: after calling parse_array: element_size: 0, element_count: 4, size 
pointern: 0xfffffffffffcf0d0
^^^ as far as I can see, the value on address 0xfffffffffffcf0d0 should be 32, 
but I have no idea, why it is not 32???

parse_array: type: ]
sizeof_type: after calling parse_array: element_size: 0, element_count: 3, size 
pointern: 0xfffffffffffcf260


here running it in gdb:

$ gdb ./a.out  
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "sparc64-unknown-openbsd4.9"...(no debugging symbols 
found)

(gdb) break objc_sizeof_type
Breakpoint 1 at 0x400ea0
(gdb) r
Starting program: /home/sebastia/a.out 
Breakpoint 1 at 0x20b7bb4d0: file encoding2.c, line 324.

Breakpoint 1, objc_sizeof_type (type=0x200c10 "[3[4i]]") at encoding2.c:324
324             size_t size = 0;
(gdb) n
325             sizeof_type(type, &size);
(gdb) s
sizeof_type (type=0x200c10 "[3[4i]]", size=0xfffffffffffe0428) at 
encoding2.c:154
154             type = objc_skip_type_qualifiers(type);
(gdb) n
155             switch (*type)
(gdb) 
197                             const char *t = type;
(gdb) 
198                             int element_size = 0;
(gdb) 
200     fprintf(stderr, "sizeof_type: before calling parse_array: element_size: 
%i, size pointern: %p\n", element_size, &element_size);
(gdb) 
sizeof_type: before calling parse_array: element_size: 0, size pointern: 
0xfffffffffffe0340
201                             int element_count = parse_array(&t, 
(type_parser)sizeof_type, &element_size);
(gdb) s
parse_array (type=0xfffffffffffe0348, callback=0x20b7b9928 <sizeof_type>, 
context=0xfffffffffffe0340) at encoding2.c:77
77              (*type)++;
(gdb) n
78              int element_count = (int)strtol(*type, (char**)type, 10);
(gdb) 
79      fprintf(stderr, "parse_array: type: %s, context a.k.a. size: %p\n", 
*type, context);
(gdb) 
parse_array: type: [4i]], context a.k.a. size: 0xfffffffffffe0340
80              *type = callback(*type, context);
(gdb) print element_count
$1 = 3
(gdb) s
sizeof_type (type=0x200c12 "[4i]]", size=0xfffffffffffe0340) at encoding2.c:154
154             type = objc_skip_type_qualifiers(type);
(gdb) n
155             switch (*type)
(gdb) 
197                             const char *t = type;
(gdb) list
192                             round_up(size, align * 8);
193                             return t;
194                     }
195                     case '[':
196                     {
197                             const char *t = type;
198                             int element_size = 0;
199                             // FIXME: aligned size
200     fprintf(stderr, "sizeof_type: before calling parse_array: element_size: 
%i, size pointern: %p\n", element_size, &element_size);
201                             int element_count = parse_array(&t, 
(type_parser)sizeof_type, &element_size);
(gdb) n
198                             int element_size = 0;
(gdb) 
200     fprintf(stderr, "sizeof_type: before calling parse_array: element_size: 
%i, size pointern: %p\n", element_size, &element_size);
(gdb) 
sizeof_type: before calling parse_array: element_size: 0, size pointern: 
0xfffffffffffe0180
201                             int element_count = parse_array(&t, 
(type_parser)sizeof_type, &element_size);
(gdb) s
parse_array (type=0xfffffffffffe0188, callback=0x20b7b9928 <sizeof_type>, 
context=0xfffffffffffe0180) at encoding2.c:77
77              (*type)++;
(gdb) 
78              int element_count = (int)strtol(*type, (char**)type, 10);
(gdb) 
strtol (nptr=0x200c13 "4i]]", endptr=0xfffffffffffe0188, base=10) at ctype.h:133
133             return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _S));
(gdb) n

...

parse_array (type=0xfffffffffffe0188, callback=0x20b7b9928 <sizeof_type>, 
context=0xfffffffffffe0180) at encoding2.c:79
79      fprintf(stderr, "parse_array: type: %s, context a.k.a. size: %p\n", 
*type, context);
(gdb) 
parse_array: type: i]], context a.k.a. size: 0xfffffffffffe0180
80              *type = callback(*type, context);
(gdb) s
sizeof_type (type=0x200c14 "i]]", size=0xfffffffffffe0180) at encoding2.c:154
154             type = objc_skip_type_qualifiers(type);
(gdb) n
155             switch (*type)
(gdb) 
14      APPLY_TYPE(int, int, Int, 'i')
(gdb) s
round_up (v=0xfffffffffffe0180, b=32) at encoding2.c:135
135             if (0 == b)
(gdb) 
140             if (*v % b)
(gdb) 
142                     *v += b - (*v % b);
(gdb) 
144     }
(gdb) n

...

(gdb) 
sizeof_type: size: 4294834688, size pointer: 0xfffffffffffe0180
sizeof_type (type=0x200c14 "i]]", size=0xfffffffffffe0180) at encoding2.c:237
237     }
(gdb) 
parse_array (type=0xfffffffffffe0188, callback=0x20b7b9928 <sizeof_type>, 
context=0xfffffffffffe0180) at encoding2.c:81
81      fprintf(stderr, "parse_array: type: %s\n", *type);
(gdb) 
parse_array: type: ]]
83              (*type)++;
(gdb) list
78              int element_count = (int)strtol(*type, (char**)type, 10);
79      fprintf(stderr, "parse_array: type: %s, context a.k.a. size: %p\n", 
*type, context);
80              *type = callback(*type, context);
81      fprintf(stderr, "parse_array: type: %s\n", *type);
82              // skip ]
83              (*type)++;
84              return element_count;
85      }
86      
87      static void parse_struct_or_union(const char **type, type_parser 
callback, void *context, char endchar)
(gdb) n
84              return element_count;
(gdb) 
85      }
(gdb) 
sizeof_type (type=0x200c12 "[4i]]", size=0xfffffffffffe0340) at encoding2.c:202
202     fprintf(stderr, "sizeof_type: after calling parse_array: element_size: 
%i, element_count: %i, size pointern: %p\n", element_size, element_count, 
&element_size);
(gdb) 
sizeof_type: after calling parse_array: element_size: 0, element_count: 4, size 
pointern: 0xfffffffffffe0180
203                             (*size) += element_size * element_count;
(gdb) print element_size
$2 = 0
(gdb) n
204                             return t;
(gdb) print *size
$3 = 4294835073
(gdb) print sizze
No symbol "sizze" in current context.
(gdb) print size
$4 = (size_t *) 0xfffffffffffe0340
(gdb) n
237     }
(gdb) 
parse_array (type=0xfffffffffffe0348, callback=0x20b7b9928 <sizeof_type>, 
context=0xfffffffffffe0340) at encoding2.c:81
81      fprintf(stderr, "parse_array: type: %s\n", *type);
(gdb) 
parse_array: type: ]
83              (*type)++;
(gdb) 
84              return element_count;
(gdb) 
85      }
(gdb) 
sizeof_type (type=0x200c10 "[3[4i]]", size=0xfffffffffffe0428) at 
encoding2.c:202
202     fprintf(stderr, "sizeof_type: after calling parse_array: element_size: 
%i, element_count: %i, size pointern: %p\n", element_size, element_count, 
&element_size);
(gdb) 
sizeof_type: after calling parse_array: element_size: 0, element_count: 3, size 
pointern: 0xfffffffffffe0340
203                             (*size) += element_size * element_count;
(gdb) 
204                             return t;
(gdb) 
237     }
(gdb) 
objc_sizeof_type (type=0x200c10 "[3[4i]]") at encoding2.c:326
326             return size / 8;
(gdb) 
327     }
(gdb) 
0x0000000000100bbc in main ()
(gdb) 
Single stepping until exit from function main, 
which has no line number information.
0
0x000000000010094c in _start ()
(gdb) 
Single stepping until exit from function _start, 
which has no line number information.

Program exited normally.
(gdb) 





Sebastian

> 
> > parse_array: type: ]
> > ^^^ fprintf after calling callback
> > 
> > element_size: 0, element_count: 3
> > ^^^ this line is before line 197
> > 
> > as far as I can see in line 194:
> > 
> >                        int element_size = 0;
> >                        // FIXME: aligned size
> >                        int element_count = parse_array(&t, 
> > (type_parser)sizeof_type, &element_size);
> 
> That FIXME should go in the bin, it was fixed ages ago, so ignore that.
> 
> > element_size goes into parse_array with a value of 0, and it also gives 
> > itself as the callback function, then in parse_array I see:
> > 
> > static int parse_array(const char **type, type_parser callback, void 
> > *context)
> > {
> >        // skip [
> >        (*type)++;
> >        int element_count = (int)strtol(*type, (char**)type, 10);
> >        *type = callback(*type, context);
> >        // skip ]
> >        (*type)++;
> >        return element_count;
> > }
> 
> This is a generic visitor function for walking arrays.  There are similar 
> ones for walking structures and unions.  All of the objc_{something}of_type() 
> functions are implemented in terms of a simple case function that handles the 
> primitive types and calls these to recursively visit complex types.
> 
> > I don't get it what the code is doing in the #define APPLY_TYPE, where the 
> > switch statement checks for the case: i ????
> > That #define is kind of puzzling me. It seems to detect the size of the "i" 
> > correctly, sizeof(typeName): 4, but it somewhere gets lost in the 
> > iterations...
> 
> Yup, that's just applying the macro defining the case for every one of the 
> valid primitive type encodings.  The APPLY_TYPE() macro is instantiated once 
> for each primitive type encoding by type_encoding_cases.h.  For the int case, 
> it matches the case 'i', rounds up size to the alignment required bit int, 
> and then adds the size of integer (the first bit is only relevant when 
> visiting structures - we need to make sure that we the field in the right 
> place).
> 
> > And I'm kind of lost too
> 
> Well, it seems to be getting lost returning the size up the stack...
> 
> David
> 
> --
> This email complies with ISO 3103
> 
 
 
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]