* Possible compiler bug with this simple program @ 2008-08-28 7:28 Jerry 2008-08-28 7:56 ` Ludovic Brenta ` (2 more replies) 0 siblings, 3 replies; 31+ messages in thread From: Jerry @ 2008-08-28 7:28 UTC (permalink / raw) The following is a program which emulates the structure of a binding to a bunch of C code (but there is no C code included here--it is all Ada). This structure exhibits a behavior which I think might be a compiler error but could be the result of incorrect declarations when running on certain machines. Specifically, the program compiles (with two warnings which are expected and OK) and runs correctly on my machine, OS X 10.4.11 running GNAT 4.3.0 (32-bit PowerPC G4). However, on someone else's box, a 64-bit Intel Duo running Debian lenny and GNAT 4.3.1-2, the program compiles but bombs at runtime with raised STORAGE_ERROR : stack overflow (or erroneous memory access) reported. However, on the Debian lenny machine, if the three lines with --*** at the end of them are commented out (they relate to Pragma-C conventions), the program compiles and runs correctly, printing out 10 lines of floats. (It also runs correctly on the OS X machine.) Here is the program, stored in two files (damn the line wraps): ========== Begin program ========== with type_declaration, Ada.Text_IO; use type_declaration, Ada.Text_IO; procedure x19a_temp is procedure mapform19(n : Integer; x : in out Real_Vector); --*** pragma Convention(C, mapform19); --*** procedure mapform19(n : Integer; x : in out Real_Vector) is begin for i in 0 .. n - 1 loop x(i) := Long_Float(i); Put_Line(Long_Float'image(x(i))); end loop; end mapform19; begin plmap(mapform19'Unrestricted_Access); end x19a_temp; package type_declaration is type Real_Vector is array (Integer range <>) of Long_Float; type Map_Form_Function_Pointer_Type is access procedure (Length_Of_x : Integer; x : in out Real_Vector); pragma Convention(Convention => C, Entity => Map_Form_Function_Pointer_Type); --*** procedure plmap(Map_Form_Function_Pointer : Map_Form_Function_Pointer_Type); end type_declaration; ========== End program ============ Now: Here are some integer declaration sizes for the OS X 32-bit version and the Debian 64-bit version. I could provide more but these should be more than sufficient if there is in fact a problem in this area. ===== OS X 32-bit sizes ===== Integer bits is 32 Long_Integer bits is 32 Long_Long_Integer bits is 64 Long_Float bits is 64 In Interfaces.C, int bits is 32 In Interfaces.C, long bits is 32 In Interfaces.C, C_float bits is 32 In Interfaces.C, double bits is 64 ===== Debian 64-bit sizes ===== Integer bits is 32 Long_Integer bits is 64 Long_Long_Integer bits is 64 Long_Float bits is 64 In Interfaces.C, int bits is 32 In Interfaces.C, long bits is 64 In Interfaces.C, C_float bits is 32 In Interfaces.C, double bits is 64 I'm inclined to think that there is a compiler problem that makes the 64-bit Debian version crash but am wondering if there could be a problem with word lengths that causes the problem. As a second problem, in the program above there is a loop line that looks like this: for i in 0 .. n - 1 loop One would normally write this as for i in x'range loop but when this runs on the OS X box, it segfaults after printing about 187 lines of bogus floats. I don't know what happens on the Debian box. However, if the -- *** lines are commented out, it runs OK on OS X. Comments? Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 7:28 Possible compiler bug with this simple program Jerry @ 2008-08-28 7:56 ` Ludovic Brenta 2008-08-28 21:08 ` Jerry 2008-08-28 8:03 ` Niklas Holsti 2008-08-28 21:16 ` Jerry 2 siblings, 1 reply; 31+ messages in thread From: Ludovic Brenta @ 2008-08-28 7:56 UTC (permalink / raw) Jerry wrote: > The following is a program which emulates the structure of a binding > to a bunch of C code (but there is no C code included here--it is all > Ada). This structure exhibits a behavior which I think might be a > compiler error but could be the result of incorrect declarations when > running on certain machines. > > Specifically, the program compiles (with two warnings which are > expected and OK) and runs correctly on my machine, OS X 10.4.11 > running GNAT 4.3.0 (32-bit PowerPC G4). However, on someone else's > box, a 64-bit Intel Duo running Debian lenny and GNAT 4.3.1-2, the > program compiles but bombs at runtime with > > raised STORAGE_ERROR : stack overflow (or erroneous memory access) > > reported. I cannot test your program now but it seems to me that perhaps you should specify the alignment of the arrays and Long_Floats. Also, it might be a good idea to double-check that on the Intel Core 2, the long floats are really 64 bits and not 80 bits wide. It could be that the compiler got that wrong but I doubt it. Also, have you tried to compare the assembly language emitted by the compiler with and without pragma Convention? (try gnatmake -c -cargs - S) [...] > As a second problem, in the program above there is a loop line that > looks like this: > > for i in 0 .. n - 1 loop > > One would normally write this as > > for i in x'range loop > > but when this runs on the OS X box, it segfaults after printing about > 187 lines of bogus floats. I don't know what happens on the Debian > box. However, if the -- *** lines are commented out, it runs OK on OS > X. This is to be expected. With convention C, there is no array anymore; instead the procedure receives a pointer to the first element of the array, so it doesn't have any information about the range. That's why it is necessary to pass the length of the array separately. HTH -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 7:56 ` Ludovic Brenta @ 2008-08-28 21:08 ` Jerry 2008-08-29 20:39 ` Ludovic Brenta 2008-09-02 22:10 ` Santiago Urueña 0 siblings, 2 replies; 31+ messages in thread From: Jerry @ 2008-08-28 21:08 UTC (permalink / raw) On Aug 28, 12:56 am, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote: > I cannot test your program now but it seems to me that perhaps you > should specify the alignment of the arrays and Long_Floats. Also, it > might be a good idea to double-check that on the Intel Core 2, the > long floats are really 64 bits and not 80 bits wide. It could be that > the compiler got that wrong but I doubt it. > And that would look something like this? for Long_Float'Alignment use 64; for Real_Vector'Alignment use ???; Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 21:08 ` Jerry @ 2008-08-29 20:39 ` Ludovic Brenta 2008-08-29 21:20 ` Jerry 2008-09-02 22:10 ` Santiago Urueña 1 sibling, 1 reply; 31+ messages in thread From: Ludovic Brenta @ 2008-08-29 20:39 UTC (permalink / raw) Jerry writes: > On Aug 28, 12:56 am, Ludovic Brenta <ludo...@ludovic-brenta.org> > wrote: >> I cannot test your program now but it seems to me that perhaps you >> should specify the alignment of the arrays and Long_Floats. Also, it >> might be a good idea to double-check that on the Intel Core 2, the >> long floats are really 64 bits and not 80 bits wide. It could be that >> the compiler got that wrong but I doubt it. >> > And that would look something like this? > > for Long_Float'Alignment use 64; > for Real_Vector'Alignment use ???; Yes. In addition, these might help: for Real_Vector'Component_Size use 64; for Real_Vector'Alignment use 64; pragma Pack (Real_Vector); I'm actually puzzled as to why the program appears to work on 32-bit platforms. I would expect a Storage_Error when accessing X (0) since, per your declaration, X'First = Integer'First = -2**31, so X (0) is probably way past the end of the array. The first thing I would try is using Natural instead of Integer as the array index subtype. If that fails, try specifying the 'Alignment and 'Component_Size. If that still fails, look at the assembly code emitted on amd64. I just received http://bugs.debian.org/497067, BTW. -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-29 20:39 ` Ludovic Brenta @ 2008-08-29 21:20 ` Jerry 2008-08-29 21:31 ` Jerry 0 siblings, 1 reply; 31+ messages in thread From: Jerry @ 2008-08-29 21:20 UTC (permalink / raw) On Aug 29, 1:39 pm, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote: > I'm actually puzzled as to why the program appears to work on 32-bit > platforms. I would expect a Storage_Error when accessing X (0) since, > per your declaration, X'First = Integer'First = -2**31, so X (0) is > probably way past the end of the array. The first thing I would try > is using Natural instead of Integer as the array index subtype. If > that fails, try specifying the 'Alignment and 'Component_Size. If > that still fails, look at the assembly code emitted on amd64. > > I just receivedhttp://bugs.debian.org/497067, BTW. > > -- > Ludovic Brenta. Thanks, Ludovic. I'll try these things and report back. The bug report that you reference is (obviously) from the person who initially noticed the problem on his 64-bit machine. In his post he asks for others to try the simple example (which is a linked tarball from the bug page that you listed) to collect more evidence that the problem is only on 64-bit machines and not 32-bit machines. Here is the tarball link that might work from here: http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=10;filename=simple_test_case.tar.gz;att=1;bug=497067 Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-29 21:20 ` Jerry @ 2008-08-29 21:31 ` Jerry 0 siblings, 0 replies; 31+ messages in thread From: Jerry @ 2008-08-29 21:31 UTC (permalink / raw) On Aug 29, 2:20 pm, Jerry <lancebo...@qwest.net> wrote: > > Thanks, Ludovic. I'll try these things and report back. > > Jerry Actually, I don't have access to a 64-bit crahsing machine so trying these things is difficult, involving e-mailing test programs to someone who does have such a machine. Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 21:08 ` Jerry 2008-08-29 20:39 ` Ludovic Brenta @ 2008-09-02 22:10 ` Santiago Urueña 1 sibling, 0 replies; 31+ messages in thread From: Santiago Urueña @ 2008-09-02 22:10 UTC (permalink / raw) > And that would look something like this? > > for Long_Float'Alignment use 64; > for Real_Vector'Alignment use ???; > Note that 'Size is specified in _bits_ but 'Alignment is in _bytes_ (well, in storage units), so I assume that you really mean: for Long_Float'Size use 64; -- bits for Long_Float'Alignment use 8; -- bytes Cheers, -- Santiago Urueña-Pascual <suruena@gmail.com> ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 7:28 Possible compiler bug with this simple program Jerry 2008-08-28 7:56 ` Ludovic Brenta @ 2008-08-28 8:03 ` Niklas Holsti 2008-08-28 15:54 ` Adam Beneschan 2008-08-28 21:01 ` Randy Brukardt 2008-08-28 21:16 ` Jerry 2 siblings, 2 replies; 31+ messages in thread From: Niklas Holsti @ 2008-08-28 8:03 UTC (permalink / raw) Jerry wrote: > The following is a program which emulates the structure of a binding > to a bunch of C code (but there is no C code included here--it is all > Ada). This structure exhibits a behavior which I think might be a > compiler error but could be the result of incorrect declarations when > running on certain machines. I suspect that one problem is using the C convention to pass a parameter that is of an unconstrained array type, see below. > Specifically, the program compiles (with two warnings which are > expected and OK) and runs correctly on my machine, OS X 10.4.11 > running GNAT 4.3.0 (32-bit PowerPC G4). However, on someone else's > box, a 64-bit Intel Duo running Debian lenny and GNAT 4.3.1-2, the > program compiles but bombs at runtime with > > raised STORAGE_ERROR : stack overflow (or erroneous memory access) > > reported. > > However, on the Debian lenny machine, if the three lines with > > --*** > > at the end of them are commented out (they relate to Pragma-C > conventions), the program compiles and runs correctly, printing out 10 > lines of floats. (It also runs correctly on the OS X machine.) > > Here is the program, stored in two files (damn the line wraps): > ... > > procedure x19a_temp is > > procedure mapform19(n : Integer; x : in out Real_Vector); --*** > pragma Convention(C, mapform19); --*** > procedure mapform19(n : Integer; x : in out Real_Vector) is ... > > > package type_declaration is > > type Real_Vector is array (Integer range <>) of Long_Float; So Real_Vector is an unconstrained array type. According to RM B.3(70), the C convention passes only a single pointer to the first element of the array, so the 'Range attribute will not be available to the subprogram. > As a second problem, in the program above there is a loop line that > looks like this: > > for i in 0 .. n - 1 loop > > One would normally write this as > > for i in x'range loop > > but when this runs on the OS X box, it segfaults after printing about > 187 lines of bogus floats. I don't know what happens on the Debian > box. However, if the -- *** lines are commented out, it runs OK on OS > X. > > Comments? My guess: the compiler implements convention C for the x parameter, which means x'range is not available, but the code for the second quoted for-loop tries to access x'range anyway -- boom! The compiler should IMHO have rejected the use of x'range here, with an error message. Using the first form of the quoted loop may trigger the same problem in the code that checks that x(i) has a valid index, i. In fact, when an Ada subprogram has an unconstrained array parameter with Convention C, it seems to me that the subprogram's body cannot make any use of individual elements of the array, because it doesn't know the index range, so the compiler should reject any indexing of such an array parameter, as well as any attempt to pass it on as a Convention Ada parameter. Conclusion: Your program tries to do something that cannot possibly work, but the compiler should have told you so. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 8:03 ` Niklas Holsti @ 2008-08-28 15:54 ` Adam Beneschan 2008-08-28 15:56 ` Adam Beneschan 2008-08-28 21:01 ` Randy Brukardt 1 sibling, 1 reply; 31+ messages in thread From: Adam Beneschan @ 2008-08-28 15:54 UTC (permalink / raw) On Aug 28, 1:03 am, Niklas Holsti <niklas.hol...@tidorum.invalid> wrote: > In fact, when an Ada subprogram has an unconstrained array > parameter with Convention C, it seems to me that the subprogram's > body cannot make any use of individual elements of the array, > because it doesn't know the index range, so the compiler should > reject any indexing of such an array parameter, as well as any > attempt to pass it on as a Convention Ada parameter. Yes, good point. For an unconstrained array parameter like X, the compiler doesn't need to know what X'Last is in order to access elements of the array---but it does need to know X'First. (X'Last is needed for range checking but not for actually accessing elements.) If you're using strictly Ada, with no Convention parameters or anything, then when mapform19 is called, the caller somehow has to make X'First and X'Last available to the routine, and then when X(I) is accessed, the generated code must compute I - X'First, multiply that by the element size, and add the result to the address of X's data. When mapform19 is called from a C routine, nothing will be passed in for X'First, but mapform19 will still try to subtract something from I, and what value it will subtract is quite random--- could be zero, could be some other garbage value. I agree that the compiler should have rejected this. But it might work to declare Real_Vector as a constrained array: type Real_Vector is array (0 .. Integer'Last) of Long_Float; Now the compiler will know that X'First is 0 and, hopefully, behave correctly. -- Adam ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 15:54 ` Adam Beneschan @ 2008-08-28 15:56 ` Adam Beneschan 0 siblings, 0 replies; 31+ messages in thread From: Adam Beneschan @ 2008-08-28 15:56 UTC (permalink / raw) On Aug 28, 8:54 am, Adam Beneschan <a...@irvine.com> wrote: > I agree that the compiler should have rejected this. But it might > work to declare Real_Vector as a constrained array: > > type Real_Vector is array (0 .. Integer'Last) of Long_Float; Or, perhaps, declare a subtype: subtype Constrained_Real_Vector is Real_Vector (0 .. Integer'Last); and use the subtype as the parameter type in mapform19 and your access- to-procedure type. -- Adam ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 8:03 ` Niklas Holsti 2008-08-28 15:54 ` Adam Beneschan @ 2008-08-28 21:01 ` Randy Brukardt 2008-08-28 21:29 ` Jerry 1 sibling, 1 reply; 31+ messages in thread From: Randy Brukardt @ 2008-08-28 21:01 UTC (permalink / raw) "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message news:48b65b3b$0$25384$4f793bc4@news.tdc.fi... ... > In fact, when an Ada subprogram has an unconstrained array parameter with > Convention C, it seems to me that the subprogram's body cannot make any > use of individual elements of the array, because it doesn't know the index > range, so the compiler should reject any indexing of such an array > parameter, as well as any attempt to pass it on as a Convention Ada > parameter. This is the subject of AI05-0002-1. (It was carried over from the Ada 95.) [Now, I have to go look this one up because I don't remember anything about what we decided...] Ah, yes: "We do not require support for C convention interfacing pragmas for unconstrained array objects, unconstrained array function results, and most unconstrained array parameters." In particular, "An implementation need not support ... an Export or Convention pragma applied to a subprogram which has a parameter of an unconstrained array subtype;". The wording goes on to include unconstrained array objects and function results as well. Note that an implementation *can* support this if it wants; some implementations do implement this with various meanings (Tucker reported that their compiler gives the array maximum bounds) and it was thought to be bad to break user programs that depend on such behaviors. But if it does support it, it ought to do something sensible (raising random exceptions doesn't count). (Also note that it is required to support pragma Import in this case, as C doesn't care about the bounds and they can just be dropped.) > Conclusion: Your program tries to do something that cannot possibly work, > but the compiler should have told you so. Well, not necessarily (see Tucker's implementation, for instance). But either it should do something defined *or* reject it at compile-time. (Janus/Ada would have rejected the Convention pragma.) In any case, it is not required to support this in any useful way, and, as it is not portable, it should be avoided. Randy. ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 21:01 ` Randy Brukardt @ 2008-08-28 21:29 ` Jerry 2008-08-30 1:00 ` Randy Brukardt 0 siblings, 1 reply; 31+ messages in thread From: Jerry @ 2008-08-28 21:29 UTC (permalink / raw) On Aug 28, 2:01 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > "Niklas Holsti" <niklas.hol...@tidorum.invalid> wrote in message > > news:48b65b3b$0$25384$4f793bc4@news.tdc.fi... > ... > > > In fact, when an Ada subprogram has an unconstrained array parameter with > > Convention C, it seems to me that the subprogram's body cannot make any > > use of individual elements of the array, because it doesn't know the index > > range, so the compiler should reject any indexing of such an array > > parameter, as well as any attempt to pass it on as a Convention Ada > > parameter. > > This is the subject of AI05-0002-1. (It was carried over from the Ada 95.) > [Now, I have to go look this one up because I don't remember anything about > what we decided...] Ah, yes: > > "We do not require support for C convention interfacing pragmas for > unconstrained > array objects, unconstrained array function results, and most unconstrained > array parameters." > > In particular, "An implementation need not support ... an Export or > Convention pragma applied to a subprogram which has a parameter of an > unconstrained array subtype;". The wording goes on to include unconstrained > array objects and function results as well. > > Note that an implementation *can* support this if it wants; some > implementations do implement this with various meanings (Tucker reported > that their compiler gives the array maximum bounds) and it was thought to be > bad to break user programs that depend on such behaviors. But if it does > support it, it ought to do something sensible (raising random exceptions > doesn't count). (Also note that it is required to support pragma Import in > this case, as C doesn't care about the bounds and they can just be dropped.) > > > Conclusion: Your program tries to do something that cannot possibly work, > > but the compiler should have told you so. > > Well, not necessarily (see Tucker's implementation, for instance). But > either it should do something defined *or* reject it at compile-time. > (Janus/Ada would have rejected the Convention pragma.) In any case, it is > not required to support this in any useful way, and, as it is not portable, > it should be avoided. > > Randy. Thanks, Randy. This is useful. Superficially, in my situation, it appears that GNAT 4.3.0 on OS X PPC supports it and GNAT 4.3.1-2 on Debian lenny on Intel duo does not support it. I suppose there could be an element of dumb luck of GNAT is not supposed to support it and it just happens to work on OS X. On the other hand, if GNAT is supposed to support it then the Debian/ Intel version is broken. The fact that warnings are issued (see my other post today where I actually list the two warnings) indicates that passing unconstrained arrays is supported but the caller had better not screw things up by trying to access outside bounds (which my example handles correctly). If that is the case, it looks like the Debian/Intel box is broken. And yes, portability isn't good, according to your report. FWIW, in the _real_ application that I am working on, plmap is written in C (and accessed from my binding by an Import). Do AdaCore people have any comments on this? Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 21:29 ` Jerry @ 2008-08-30 1:00 ` Randy Brukardt 2008-08-30 4:47 ` Jerry 0 siblings, 1 reply; 31+ messages in thread From: Randy Brukardt @ 2008-08-30 1:00 UTC (permalink / raw) "Jerry" <lanceboyle@qwest.net> wrote in message news:97b1150b-cb8f-4972-b594-2ae59af84147@x16g2000prn.googlegroups.com... ... >FWIW, in the _real_ application that I am working on, plmap is written >in C (and accessed from my binding by an Import). Interestingly, that's completely different. That *should* work on all Ada compilers (note that the wording specifically excludes unconstrained parameters for pragma Import). This example program is unportable garbage, unfortunately, because of AI05-0002-1, and also because of B.1(38.1/2) (the "buyer beware" clause: there is no requirement that an Ada program actually work as expected if you force its conventions to another language (like C). Admittedly, this is a bit strange. In this case, C works fine as the receiver of such a call because it has no need to know the bounds of the array passed. (And if it does, they're going to be passed explicitly.) But Ada does need to know those bounds, and you can't even pass them explicitly because the Ada compiler will have to assume something for the lower bound in order to generate indexing operations (and that may be different than what you intended). The net effect is that the example program doesn't prove anything useful. It would need to import an actual C subprogram in order to be a useful test. Randy. ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-30 1:00 ` Randy Brukardt @ 2008-08-30 4:47 ` Jerry 2008-09-01 11:19 ` Jerry 0 siblings, 1 reply; 31+ messages in thread From: Jerry @ 2008-08-30 4:47 UTC (permalink / raw) On Aug 29, 6:00 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > "Jerry" <lancebo...@qwest.net> wrote in message > > news:97b1150b-cb8f-4972-b594-2ae59af84147@x16g2000prn.googlegroups.com... > ... > > >FWIW, in the _real_ application that I am working on, plmap is written > >in C (and accessed from my binding by an Import). > > Interestingly, that's completely different. That *should* work on all Ada > compilers (note that the wording specifically excludes unconstrained > parameters for pragma Import). > > This example program is unportable garbage, unfortunately, because of > AI05-0002-1, and also because of B.1(38.1/2) (the "buyer beware" clause: > there is no requirement that an Ada program actually work as expected if you > force its conventions to another language (like C). > > Admittedly, this is a bit strange. In this case, C works fine as the > receiver of such a call because it has no need to know the bounds of the > array passed. (And if it does, they're going to be passed explicitly.) But > Ada does need to know those bounds, and you can't even pass them explicitly > because the Ada compiler will have to assume something for the lower bound > in order to generate indexing operations (and that may be different than > what you intended). > > The net effect is that the example program doesn't prove anything useful. It > would need to import an actual C subprogram in order to be a useful test. > > Randy. OK--this clears things up for me. And possibly validates the reason I wrote the _real_ application the way that I did, thinking that C arrays always starts from 0 so passing the length along as a separate parameter should work. But it looks like in testing (and posting) an all-Ada example I muddied the situation--or worse--used a completely different example from what my original code was. I'll see if I can make another example where plmap is a simple program in C that is Import-ed and see if it bombs on a 64-bit computer. Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-30 4:47 ` Jerry @ 2008-09-01 11:19 ` Jerry 2008-09-03 4:22 ` Jerry 0 siblings, 1 reply; 31+ messages in thread From: Jerry @ 2008-09-01 11:19 UTC (permalink / raw) On Aug 29, 9:47 pm, Jerry <lancebo...@qwest.net> wrote: > On Aug 29, 6:00 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > > "Jerry" <lancebo...@qwest.net> wrote in message > > > >FWIW, in the _real_ application that I am working on, plmap is written > > >in C (and accessed from my binding by an Import). > > > Interestingly, that's completely different. That *should* work on all Ada > > compilers (note that the wording specifically excludes unconstrained > > parameters for pragma Import). <snip> > > Randy. > > I'll see if I can make another example where plmap is a simple program > in C that is Import-ed and see if it bombs on a 64-bit computer. > > Jerry I've changed the simple example so that plmap is implemented in C. The results are the same as with the all-Ada version: It runs OK on my OS X 10.4.11 machine, PPC, Ada 4.3, but my colleague reports that it crashes on his 64-bit machine which I believe is still the 64-bit Intel Duo running Debian lenny and GNAT 4.3.1-2. The crash looks the same as before: raised STORAGE_ERROR : stack overflow (or erroneous memory access) The example as either a zip or tarball which includes the very short code files and a three-line bash script can be downloaded from my site here: http://public.me.com/oscarruitt or directly here: http://public.me.com/oscarruitt/simple_test_case_with_c.zip http://idisk.mac.com/oscarruitt-Public/simple_test_case_with_c.zip (Let me know if these don't work.) And here is the code directly: -- x19a_temp.adb with type_declaration, Ada.Text_IO; use type_declaration, Ada.Text_IO; procedure x19a_temp is procedure mapform19(n : Integer; x : in out Real_Vector); pragma Convention(C, mapform19); procedure mapform19(n : Integer; x : in out Real_Vector) is begin for i in 0 .. n - 1 loop x(i) := Long_Float(i); Put_Line(Long_Float'image(x(i))); end loop; end mapform19; begin plmap(mapform19'Unrestricted_Access); end x19a_temp; -- type_declaration.ads package type_declaration is type Real_Vector is array (Integer range <>) of Long_Float; type Map_Form_Function_Pointer_Type is access procedure (Length_Of_x : Integer; x : in out Real_Vector); pragma Convention(Convention => C, Entity => Map_Form_Function_Pointer_Type); procedure plmap(Map_Form_Function_Pointer : Map_Form_Function_Pointer_Type); pragma Import(C, plmap, "plmap"); end type_declaration; /* plplot.h */ #include <stdint.h> void plmap( void (*mapform)(int32_t, double *)); /* plmap.c */ #include "plplot.h" void plmap( void (*mapform)(int32_t, double *) ) { int32_t n; double xx[10]; n = 10; (*mapform)(n, xx); } # Compile and run with these lines: gcc -c plmap.c gnatmake x19a_temp.adb -largs plmap.o ./x19a_temp Thanks once again. Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-01 11:19 ` Jerry @ 2008-09-03 4:22 ` Jerry 2008-09-03 14:20 ` Adam Beneschan 0 siblings, 1 reply; 31+ messages in thread From: Jerry @ 2008-09-03 4:22 UTC (permalink / raw) On Sep 1, 4:19 am, Jerry <lancebo...@qwest.net> wrote: > On Aug 29, 9:47 pm, Jerry <lancebo...@qwest.net> wrote: > > > On Aug 29, 6:00 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > > > "Jerry" <lancebo...@qwest.net> wrote in message > > > > >FWIW, in the _real_ application that I am working on, plmap is written > > > >in C (and accessed from my binding by an Import). > > > > Interestingly, that's completely different. That *should* work on all Ada > > > compilers (note that the wording specifically excludes unconstrained > > > parameters for pragma Import). > <snip> > > > Randy. > > > I'll see if I can make another example where plmap is a simple program > > in C that is Import-ed and see if it bombs on a 64-bit computer. > > > Jerry > > I've changed the simple example so that plmap is implemented in C. > There haven't been any responses about the above post with mixed Ada-C code from this list but I have reports from the other developers on my project that it also runs OK on 32-bit systems but hangs on 64-bit systems. Unless somebody has further comments in a few days about why this isn't a bug, I'm going to report it as such. Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-03 4:22 ` Jerry @ 2008-09-03 14:20 ` Adam Beneschan 2008-09-04 0:22 ` Jerry 0 siblings, 1 reply; 31+ messages in thread From: Adam Beneschan @ 2008-09-03 14:20 UTC (permalink / raw) On Sep 2, 9:22 pm, Jerry <lancebo...@qwest.net> wrote: > On Sep 1, 4:19 am, Jerry <lancebo...@qwest.net> wrote: > > > On Aug 29, 9:47 pm, Jerry <lancebo...@qwest.net> wrote: > > > > On Aug 29, 6:00 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > > > > "Jerry" <lancebo...@qwest.net> wrote in message > > > > > >FWIW, in the _real_ application that I am working on, plmap is written > > > > >in C (and accessed from my binding by an Import). > > > > > Interestingly, that's completely different. That *should* work on all Ada > > > > compilers (note that the wording specifically excludes unconstrained > > > > parameters for pragma Import). > > <snip> > > > > Randy. > > > > I'll see if I can make another example where plmap is a simple program > > > in C that is Import-ed and see if it bombs on a 64-bit computer. > > > > Jerry > > > I've changed the simple example so that plmap is implemented in C. > > There haven't been any responses about the above post with mixed Ada-C > code from this list but I have reports from the other developers on my > project that it also runs OK on 32-bit systems but hangs on 64-bit > systems. > > Unless somebody has further comments in a few days about why this > isn't a bug, I'm going to report it as such. Several of us have pointed out that it's a bad idea to use an unconstrained array type (i.e. Real_Vector) as a parameter to an imported routine (or a routine with convention C), but the above code still did it. -- Adam ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-03 14:20 ` Adam Beneschan @ 2008-09-04 0:22 ` Jerry 2008-09-04 1:18 ` Adam Beneschan ` (2 more replies) 0 siblings, 3 replies; 31+ messages in thread From: Jerry @ 2008-09-04 0:22 UTC (permalink / raw) On Sep 3, 7:20 am, Adam Beneschan <a...@irvine.com> wrote: > > Several of us have pointed out that it's a bad idea to use an > unconstrained array type (i.e. Real_Vector) as a parameter to an > imported routine (or a routine with convention C), but the above code > still did it. > > -- Adam In about a hundred cases in this same binding project, I have passed an unconstrained array (and its length) as a parameter to an Imported C subprogram without consequence--no warnings, no errors, no hangs--on several kinds of machines (32-bit and 64-bit). This seems to be allowed by ARM B.3.70: "An Ada parameter of an array type with component type T, of any mode, is passed as a t* argument to a C function, where t is the C type corresponding to the Ada type T." There is no restriction on unconstrained array types. The reason that I posted the modified code (mixed Ada and C) is that Randy's post indicated that it should work. In one instance (of the "hundred"), I "rename" one of these Imported C subprograms (it has two unconstrained arrays and their length as parameters). At the point of the "rename," GNAT generates two warnings, "foreign caller must pass bounds explicitly," and "type of argument "plfill.y" is unconstrained array." (plfill is the procedure name and y is one of the unconstrained arrays. A similar pair of warnings is generated for the other passed unconstrained array.) The purpose for renaming the procedure, which is originally declared as an Import with C conventions in another package (without warnings), is to allow the user to pass it as a callback to another Imported C subprogram. This works without problems. The difference between the two cases ([1] described above, herein, and [2] the code in mixed Ada and C that I posted earlier), is that in [1], both the called procedure and the callback procedure are written in C, and the in problematic code [2], the called subprogram is in C (plmap) but the callback (mapform19) is written in Ada, with C conventions. In a third scenario in the binding project [3], Ada successfully calls an Imported procedure written in C and passes a callback written in Ada with C conventions; this closely resembles the problematic code [2] except that in [3], the callback function is passed with 'Access and in [2] it is passed with 'Unrestricted_Access. Also, [3] doesn't pass an unconstrained array. (I don't see how to make [2] work with 'access without requiring the user to put the user-written callback into the binding package.) Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-04 0:22 ` Jerry @ 2008-09-04 1:18 ` Adam Beneschan 2008-09-04 3:53 ` Randy Brukardt 2008-09-04 1:31 ` Jeffrey R. Carter 2008-09-04 20:49 ` Simon Wright 2 siblings, 1 reply; 31+ messages in thread From: Adam Beneschan @ 2008-09-04 1:18 UTC (permalink / raw) On Sep 3, 5:22 pm, Jerry <lancebo...@qwest.net> wrote: > On Sep 3, 7:20 am, Adam Beneschan <a...@irvine.com> wrote: > > > > > Several of us have pointed out that it's a bad idea to use an > > unconstrained array type (i.e. Real_Vector) as a parameter to an > > imported routine (or a routine with convention C), but the above code > > still did it. > > > -- Adam > > In about a hundred cases in this same binding project, I have passed > an unconstrained array (and its length) as a parameter to an Imported > C subprogram without consequence--no warnings, no errors, no hangs--on > several kinds of machines (32-bit and 64-bit). This seems to be > allowed by ARM B.3.70: "An Ada parameter of an array type with > component type T, of any mode, is passed as a t* argument to a C > function, where t is the C type corresponding to the Ada type T." > There is no restriction on unconstrained array types. This talks about passing an unconstrained array parameter *from* an Ada routine *to* a C function. You're doing more than that---you're having the C function pass the unconstrained array parameter back *to* an Ada routine, which the manual says nothing about. > The reason that I posted the modified code (mixed Ada and C) is that > Randy's post indicated that it should work. I think there must be a misunderstanding. In one of his posts he seemed to imply that it should work to pass an unconstrained array parameter to a C routine on all Ada compilers, but he then referred to the program as "unportable garbage". In another post he said that either the Ada compiler should document what should happen when an unconstrained array parameter is passed from C to Ada and implement it that way consistently (e.g. it should just decree that the lower bound is 0 and document it that way---but that's just one possible way of handling it), or reject the program. GNAT apparently doesn't do either so it's defective. The bug in GNAT, I believe, is that it compiles your Ada program in the first place---just my opinion. > In one instance (of the "hundred"), I "rename" one of these Imported C > subprograms (it has two unconstrained arrays and their length as > parameters). At the point of the "rename," GNAT generates two > warnings, "foreign caller must pass bounds explicitly," and "type of > argument "plfill.y" is unconstrained array." (plfill is the procedure > name and y is one of the unconstrained arrays. A similar pair of > warnings is generated for the other passed unconstrained array.) The > purpose for renaming the procedure, which is originally declared as an > Import with C conventions in another package (without warnings), is to > allow the user to pass it as a callback to another Imported C > subprogram. This works without problems. > > The difference between the two cases ([1] described above, herein, and > [2] the code in mixed Ada and C that I posted earlier), is that in > [1], both the called procedure and the callback procedure are written > in C, and the in problematic code [2], the called subprogram is in C > (plmap) but the callback (mapform19) is written in Ada, with C > conventions. Yup, this is not surprising at all to me. And if you go back and reread my earlier post, I believe I explained pretty thoroughly why this is happening, and also gave you a solution. Don't use an unconstrained array type in your callback routine. Period. You can use unconstrained arrays when calling C routines from Ada; but if you're going to call Ada routines from C, don't. -- Adam ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-04 1:18 ` Adam Beneschan @ 2008-09-04 3:53 ` Randy Brukardt 0 siblings, 0 replies; 31+ messages in thread From: Randy Brukardt @ 2008-09-04 3:53 UTC (permalink / raw) "Adam Beneschan" <adam@irvine.com> wrote in message news:90006a35-e933-40f1-9a76-5698b0ce75d1@s20g2000prd.googlegroups.com... ... >> The difference between the two cases ([1] described above, herein, and >> [2] the code in mixed Ada and C that I posted earlier), is that in >> [1], both the called procedure and the callback procedure are written >> in C, and the in problematic code [2], the called subprogram is in C >> (plmap) but the callback (mapform19) is written in Ada, with C >> conventions. > > Yup, this is not surprising at all to me. And if you go back and > reread my earlier post, I believe I explained pretty thoroughly why > this is happening, and also gave you a solution. Don't use an > unconstrained array type in your callback routine. Period. You can > use unconstrained arrays when calling C routines from Ada; but if > you're going to call Ada routines from C, don't. Right. It is *only* OK to use an unconstrained array parameter in a subprogram that has pragma Import. It is *not* OK in any other context for C (objects, subprograms with Convention or Export pragmas, function returns of any kind). Your program is still using pragma Convention and you are still having C call Ada with an unconstrained parameter. You can't do that portably. I may have not looked carefully enough at your original program; I presumed that reason you were using pragma Convention was so that you could write the routine in Ada, and that it would be replaced by pragma Import in the real program. If that was wrong, I probably mislead you. Randy. ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-04 0:22 ` Jerry 2008-09-04 1:18 ` Adam Beneschan @ 2008-09-04 1:31 ` Jeffrey R. Carter 2008-09-04 14:35 ` Adam Beneschan 2008-09-05 8:17 ` Ludovic Brenta 2008-09-04 20:49 ` Simon Wright 2 siblings, 2 replies; 31+ messages in thread From: Jeffrey R. Carter @ 2008-09-04 1:31 UTC (permalink / raw) Jerry wrote: > > In about a hundred cases in this same binding project, I have passed > an unconstrained array (and its length) as a parameter to an Imported > C subprogram without consequence--no warnings, no errors, no hangs--on > several kinds of machines (32-bit and 64-bit). This seems to be > allowed by ARM B.3.70: "An Ada parameter of an array type with > component type T, of any mode, is passed as a t* argument to a C > function, where t is the C type corresponding to the Ada type T." > There is no restriction on unconstrained array types. Yes, but you're passing a pointer to an Ada convention-C subprogram to a C function, and C is calling that subprogram. The subprogram has a an unconstrained array parameter. This says nothing about what happens when C calls Ada. Ada needs to know what the lower bound of this array parameter is, and apparently your compiler is getting it wrong. Using a constrained array type with a lower bound of zero and an upper bound as large or larger than can occur would be the best choice for this situation. -- Jeff Carter "I fart in your general direction." Monty Python & the Holy Grail 05 ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-04 1:31 ` Jeffrey R. Carter @ 2008-09-04 14:35 ` Adam Beneschan 2008-09-04 14:42 ` Jacob Sparre Andersen 2008-09-06 3:03 ` Jerry 2008-09-05 8:17 ` Ludovic Brenta 1 sibling, 2 replies; 31+ messages in thread From: Adam Beneschan @ 2008-09-04 14:35 UTC (permalink / raw) On Sep 3, 6:31 pm, "Jeffrey R. Carter" <spam.jrcarter....@spam.acm.org> wrote: > Ada needs to know what the lower bound of this array parameter is, and > apparently your compiler is getting it wrong. One other thing that probably ought to be mentioned: It's possible that the compiler is trying to determine the lower bound by looking at some memory location where it expects the lower bound to be, but in reality (since the Ada routine is being called from C) contains a random value previously used for something else. My experience is that memory locations with random values contain zero a high percentage of the time, so it would make sense that the program would happen to work on some platforms, or on some targets. If I understood the original post correctly, the program seemed to be working on some platforms but not others, and it could well be because of this random factor. It doesn't mean the compiler or the program were correct on those platforms. > Using a constrained array type or subtype, I think. > with a lower bound of zero and an upper bound as large or larger than can occur > would be the best choice for this situation. -- Adam ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-04 14:35 ` Adam Beneschan @ 2008-09-04 14:42 ` Jacob Sparre Andersen 2008-09-06 3:03 ` Jerry 1 sibling, 0 replies; 31+ messages in thread From: Jacob Sparre Andersen @ 2008-09-04 14:42 UTC (permalink / raw) [ calling an Ada function from C with an array argument ] Isn't this a case, where package Interfaces.C.Pointers is appropriate to use? (Despite the name, it seems mostly to be concerned with C-style "arrays".) Greetings, Jacob -- "Never trust a statistic you have not falsified yourself." ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-04 14:35 ` Adam Beneschan 2008-09-04 14:42 ` Jacob Sparre Andersen @ 2008-09-06 3:03 ` Jerry 1 sibling, 0 replies; 31+ messages in thread From: Jerry @ 2008-09-06 3:03 UTC (permalink / raw) Thanks for all the help, everyone. I have a report back that the program (both the simple example and the actual application) work correctly on at least one of the formerly hanging machines. As some of you suggested, the fix was to use a constrained array starting from 0 and making it long enough to handle any reasonable usage. Not especially elegant, but good enough. Jerry ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-04 1:31 ` Jeffrey R. Carter 2008-09-04 14:35 ` Adam Beneschan @ 2008-09-05 8:17 ` Ludovic Brenta 2008-09-05 15:56 ` Adam Beneschan 2008-09-05 17:09 ` Jeffrey R. Carter 1 sibling, 2 replies; 31+ messages in thread From: Ludovic Brenta @ 2008-09-05 8:17 UTC (permalink / raw) Jeff Carter writes: > Ada needs to know what the lower bound of this array parameter is, and > apparently your compiler is getting it wrong. Using a constrained array type > with a lower bound of zero and an upper bound as large or larger than can occur > would be the best choice for this situation. I would actually use a local, constrained array type of exactly the required length: procedure Ada_Callback (Length : in Natural; Array_Address : in System.Address); pragma Convention (C, Ada_Callback); procedure Ada_Callback (Length : in Natural; Array_Address : in System.Address) is type Constrained_Array_Subtype is array (1 .. Length) of Long_Float; X : Constrained_Array_Subtype; for X'Address use Array_Address; pragma Import (Ada, X); -- disable default initialization begin ... end Ada_Callback; I know using System.Address may seem unholy at first sight but this implementation is explicit about what it does -- dangerous things with an address received from the unsafe "external world" outside the control of the compiler. Comments? -- Ludovic Brenta. ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-05 8:17 ` Ludovic Brenta @ 2008-09-05 15:56 ` Adam Beneschan 2008-09-05 17:09 ` Jeffrey R. Carter 1 sibling, 0 replies; 31+ messages in thread From: Adam Beneschan @ 2008-09-05 15:56 UTC (permalink / raw) On Sep 5, 1:17 am, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote: > Jeff Carter writes: > > Ada needs to know what the lower bound of this array parameter is, and > > apparently your compiler is getting it wrong. Using a constrained array type > > with a lower bound of zero and an upper bound as large or larger than can occur > > would be the best choice for this situation. > > I would actually use a local, constrained array type of exactly the > required length: > > procedure Ada_Callback (Length : in Natural; Array_Address : in > System.Address); > pragma Convention (C, Ada_Callback); > > procedure Ada_Callback (Length : in Natural; Array_Address : in > System.Address) is > type Constrained_Array_Subtype is array (1 .. Length) of > Long_Float; or array (0 .. Length - 1)... > X : Constrained_Array_Subtype; > for X'Address use Array_Address; > pragma Import (Ada, X); -- disable default initialization > begin > ... > end Ada_Callback; > > I know using System.Address may seem unholy at first sight but this > implementation is explicit about what it does -- dangerous things with > an address received from the unsafe "external world" outside the > control of the compiler. > > Comments? Doing it your way has a better chance of being portable. Earlier, others and I have recommended using a constrained array subtype (with a large upper bound) as a parameter, and I'd guess that will have the desired effect on most compilers, but you never know---sometimes compilers have unexpected ways of doing things. If you're sure that a System.Address will look just like a C (void *) or (double *) type, and will be passed in the same way, then using a System.Address parameter will make pretty sure that things will work right. -- Adam ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-05 8:17 ` Ludovic Brenta 2008-09-05 15:56 ` Adam Beneschan @ 2008-09-05 17:09 ` Jeffrey R. Carter 1 sibling, 0 replies; 31+ messages in thread From: Jeffrey R. Carter @ 2008-09-05 17:09 UTC (permalink / raw) Ludovic Brenta wrote: > > I know using System.Address may seem unholy at first sight but this > implementation is explicit about what it does -- dangerous things with > an address received from the unsafe "external world" outside the > control of the compiler. > > Comments? There's no guarantee that a C pointer and Ada's System.Address are the same thing. Of course, to be safe, you shouldn't use Integer, Long_Float, or any other type not declared in Interfaces.C and its children, or otherwise declared convention C. So really this should be something like type Double_Ptr is access all Interfaces.C.Double; pragma Convention (C, Double_Ptr); procedure Ada_Callback (Length : Interfaces.C.Int; First_Component : Double_Ptr); pragma Convention (C, Ada_Callback); And then mess with pointer arithmetic (: But a constrained array type is just as safe: type C_List is array (Interfaces.C.Int range 0 .. Interfaces.C.Int'Last) of aliased Interfaces.C.Double; pragma Convention (C, C_List); procedure Ada_Callback (Length : Interfaces.C.Int; List : C_List); pragma Convention (C, Ada_Callback); And much easier to use. -- Jeff Carter "You me on the head hitted." Never Give a Sucker an Even Break 108 ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-09-04 0:22 ` Jerry 2008-09-04 1:18 ` Adam Beneschan 2008-09-04 1:31 ` Jeffrey R. Carter @ 2008-09-04 20:49 ` Simon Wright 2 siblings, 0 replies; 31+ messages in thread From: Simon Wright @ 2008-09-04 20:49 UTC (permalink / raw) Jerry <lanceboyle@qwest.net> writes: > The difference between the two cases ([1] described above, herein, and > [2] the code in mixed Ada and C that I posted earlier), is that in > [1], both the called procedure and the callback procedure are written > in C, and the in problematic code [2], the called subprogram is in C > (plmap) but the callback (mapform19) is written in Ada, with C > conventions. Referring to [2], you also need to be careful (GNAT & VxWorks at least) if the C calling thread isn't an Ada task; the Ada code expects the VxWorks TCB to contain a pointer to auxiliary Ada RTS structures. Call GNAT.Threads.Register_Thread (as early as possible in the called Ada subprogram, I guess! before it needs the secondary stack, for example) ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 7:28 Possible compiler bug with this simple program Jerry 2008-08-28 7:56 ` Ludovic Brenta 2008-08-28 8:03 ` Niklas Holsti @ 2008-08-28 21:16 ` Jerry 2008-08-29 7:41 ` Niklas Holsti 2 siblings, 1 reply; 31+ messages in thread From: Jerry @ 2008-08-28 21:16 UTC (permalink / raw) On Aug 28, 12:28 am, Jerry <lancebo...@qwest.net> wrote: > The following is a program which emulates the structure of a binding > to a bunch of C code (but there is no C code included here--it is all > Ada). This structure exhibits a behavior which I think might be a > compiler error but could be the result of incorrect declarations when > running on certain machines. > > Specifically, the program compiles (with two warnings which are > expected and OK) and runs correctly on my machine, OS X 10.4.11 > running GNAT 4.3.0 (32-bit PowerPC G4). However, on someone else's > box, a 64-bit Intel Duo running Debian lenny and GNAT 4.3.1-2, the > program compiles but bombs at runtime with > > raised STORAGE_ERROR : stack overflow (or erroneous memory access) > > reported. > > However, on the Debian lenny machine, if the three lines with > > --*** > > at the end of them are commented out (they relate to Pragma-C > conventions), the program compiles and runs correctly, printing out 10 > lines of floats. (It also runs correctly on the OS X machine.) > > Here is the program, stored in two files (damn the line wraps): > > ========== Begin program ========== > > with > type_declaration, > Ada.Text_IO; > use > type_declaration, > Ada.Text_IO; > > procedure x19a_temp is > > procedure mapform19(n : Integer; x : in out Real_Vector); --*** > pragma Convention(C, mapform19); --*** > > procedure mapform19(n : Integer; x : in out Real_Vector) is > begin > for i in 0 .. n - 1 loop > x(i) := Long_Float(i); > Put_Line(Long_Float'image(x(i))); > end loop; > end mapform19; > > begin > plmap(mapform19'Unrestricted_Access); > end x19a_temp; > > package type_declaration is > > type Real_Vector is array (Integer range <>) of Long_Float; > > type Map_Form_Function_Pointer_Type is access > procedure (Length_Of_x : Integer; x : in out Real_Vector); > pragma Convention(Convention => C, > Entity => Map_Form_Function_Pointer_Type); --*** > > procedure plmap(Map_Form_Function_Pointer : > Map_Form_Function_Pointer_Type); > > end type_declaration; > > ========== End program ============ > > Now: Here are some integer declaration sizes for the OS X 32-bit > version and the Debian 64-bit version. I could provide more but these > should be more than sufficient if there is in fact a problem in this > area. > > ===== OS X 32-bit sizes ===== > Integer bits is 32 > Long_Integer bits is 32 > Long_Long_Integer bits is 64 > Long_Float bits is 64 > In Interfaces.C, int bits is 32 > In Interfaces.C, long bits is 32 > In Interfaces.C, C_float bits is 32 > In Interfaces.C, double bits is 64 > > ===== Debian 64-bit sizes ===== > Integer bits is 32 > Long_Integer bits is 64 > Long_Long_Integer bits is 64 > Long_Float bits is 64 > In Interfaces.C, int bits is 32 > In Interfaces.C, long bits is 64 > In Interfaces.C, C_float bits is 32 > In Interfaces.C, double bits is 64 > > I'm inclined to think that there is a compiler problem that makes the > 64-bit Debian version crash but am wondering if there could be a > problem with word lengths that causes the problem. > > As a second problem, in the program above there is a loop line that > looks like this: > > for i in 0 .. n - 1 loop > > One would normally write this as > > for i in x'range loop > > but when this runs on the OS X box, it segfaults after printing about > 187 lines of bogus floats. I don't know what happens on the Debian > box. However, if the -- *** lines are commented out, it runs OK on OS > X. > > Comments? > > Jerry Thanks, everybody, for the comments. As for the second problem ( in 0 .. n - 1 loop versus for i in x'range loop), my main concern (since I have a workaround--the first form) is that the compiler allows the second form at all. It looks like a situation where a simple syntactically correct program bombs. Also, I should have mentioned that the two warnings that are emitted at compile time as a result of passing the unconstrained array via C conventions are this: x19a_temp.adb:10:38: warning: type of argument "mapform19.x" is unconstrained array x19a_temp.adb:10:38: warning: foreign caller must pass bounds explicitly I get this pair of warnings in other places where I do some callbacks to C so I expected to see it here, as well, and I'm fine with that. Also, I apologize for not including the body part of type_declarations which looks like this: ========== Begin body part ========== package body type_declaration is procedure plmap(Map_Form_Function_Pointer : Map_Form_Function_Pointer_Type) is xx : Real_Vector(0 .. 9); begin Map_Form_Function_Pointer(xx'length, xx); end plmap; end type_declaration; ========== End body part ========== Does the declaration of xx here as a constrained array change anyone's comments about array boundaries not being known later? ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-28 21:16 ` Jerry @ 2008-08-29 7:41 ` Niklas Holsti 2008-08-30 0:50 ` Randy Brukardt 0 siblings, 1 reply; 31+ messages in thread From: Niklas Holsti @ 2008-08-29 7:41 UTC (permalink / raw) Jerry wrote: > On Aug 28, 12:28 am, Jerry <lancebo...@qwest.net> wrote: > >>The following is a program which emulates the structure of a binding >>to a bunch of C code (but there is no C code included here--it is all >>Ada). This structure exhibits a behavior which I think might be a >>compiler error but could be the result of incorrect declarations when >>running on certain machines. >> >>Specifically, the program compiles (with two warnings which are >>expected and OK) and runs correctly on my machine, OS X 10.4.11 >>running GNAT 4.3.0 (32-bit PowerPC G4). However, on someone else's >>box, a 64-bit Intel Duo running Debian lenny and GNAT 4.3.1-2, the >>program compiles but bombs at runtime with >> >>raised STORAGE_ERROR : stack overflow (or erroneous memory access) >> >>reported. >> >>However, on the Debian lenny machine, if the three lines with >> >> --*** >> >>at the end of them are commented out (they relate to Pragma-C >>conventions), the program compiles and runs correctly, printing out 10 >>lines of floats. (It also runs correctly on the OS X machine.) >> >>Here is the program, stored in two files (damn the line wraps): >> >>========== Begin program ========== >> >>with >> type_declaration, >> Ada.Text_IO; >>use >> type_declaration, >> Ada.Text_IO; >> >>procedure x19a_temp is >> >> procedure mapform19(n : Integer; x : in out Real_Vector); --*** >> pragma Convention(C, mapform19); --*** >> >> procedure mapform19(n : Integer; x : in out Real_Vector) is >> begin >> for i in 0 .. n - 1 loop >> x(i) := Long_Float(i); >> Put_Line(Long_Float'image(x(i))); >> end loop; >> end mapform19; >> >>begin >> plmap(mapform19'Unrestricted_Access); >>end x19a_temp; >> >>package type_declaration is >> >> type Real_Vector is array (Integer range <>) of Long_Float; >> >> type Map_Form_Function_Pointer_Type is access >> procedure (Length_Of_x : Integer; x : in out Real_Vector); >> pragma Convention(Convention => C, >> Entity => Map_Form_Function_Pointer_Type); --*** >> >> procedure plmap(Map_Form_Function_Pointer : >>Map_Form_Function_Pointer_Type); >> >>end type_declaration; >> >>========== End program ============ ... >>As a second problem, in the program above there is a loop line that >>looks like this: >> >> for i in 0 .. n - 1 loop >> >>One would normally write this as >> >> for i in x'range loop >> >>but when this runs on the OS X box, it segfaults after printing about >>187 lines of bogus floats. I don't know what happens on the Debian >>box. However, if the -- *** lines are commented out, it runs OK on OS >>X. >> >>Comments? >> >>Jerry > > > > Thanks, everybody, for the comments. > > As for the second problem ( in 0 .. n - 1 loop versus for i in x'range > loop), my main concern (since I have a workaround--the first form) ... Even if the workaround using "in 0 .. n - 1" works on a given compiler and machine, according to Randy this depends on non-standard (ie. generally unportable) features of the compiler. For example, Randy mentioned that Tucker's compiler would give the x-array "maximum bounds", which in this case seems to mean Integer'First .. Integer'Last, and so x(0) would lie somewhere far beyond the actual array in memory. For "in 0 .. n-1" to work on Tucker's compiler, you should probably declare Real_Vector using Natural indices instead of Integer indices, to make the "maximum bounds" be 0 .. Natural'Last. > Also, I should have mentioned that the two warnings that are emitted > at compile time as a result of passing the unconstrained array via C > conventions are this: > > x19a_temp.adb:10:38: warning: type of argument "mapform19.x" is > unconstrained array > x19a_temp.adb:10:38: warning: foreign caller must pass bounds > explicitly > > I get this pair of warnings in other places where I do some callbacks > to C so I expected to see it here, as well, and I'm fine with that. In C code there is no problem, as all arrays start at index 0. (Which, of course, leads to other problems, but they are on the design level :-) > Also, I apologize for not including the body part of type_declarations > which looks like this: > > ========== Begin body part ========== > > package body type_declaration is > > procedure plmap(Map_Form_Function_Pointer : > Map_Form_Function_Pointer_Type) is > xx : Real_Vector(0 .. 9); > begin > Map_Form_Function_Pointer(xx'length, xx); > end plmap; > > end type_declaration; > > ========== End body part ========== > > Does the declaration of xx here as a constrained array change anyone's > comments about array boundaries not being known later? Not for me. Although the "xx" *object* is constrained, the *type* is still unconstrained. This is the point: Convention C means that the actual index range of "xx", although known at the point of call, is not passed to Map_Form_Function_Pointer.all. If I understand Randy's explanation correctly, it does not even help to pass the index range explicitly (instead of passing just the length, as in your code), because the compiler invents some index range of its own for accessing the Convention C unconstrained-array parameter within the Ada body of the subprogram. For this code to work, you must just know what this invented index-range is, in your compiler. -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ . ^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: Possible compiler bug with this simple program 2008-08-29 7:41 ` Niklas Holsti @ 2008-08-30 0:50 ` Randy Brukardt 0 siblings, 0 replies; 31+ messages in thread From: Randy Brukardt @ 2008-08-30 0:50 UTC (permalink / raw) "Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message news:48b7a778$0$23608$4f793bc4@news.tdc.fi... ... > If I understand Randy's explanation correctly, it does not even help to > pass the index range explicitly (instead of passing just the length, as in > your code), because the compiler invents some index range of its own for > accessing the Convention C unconstrained-array parameter within the Ada > body of the subprogram. For this code to work, you must just know what > this invented index-range is, in your compiler. That is correct. For Ada, the passed in object must have some bounds, and the compiler either invents them (hopefully documented somewhere), or preferably, rejects the representation clause in the first place. I believe early drafts of this AI required rejection, but there was enough concern with compatibility that that was weakened in the final version. In any case, this sort of thing is not portable in any way; you have to figure out what a particular compiler does in order to use it at all. The OP should keep in mind that an appropriate bug fix for GNAT is to reject this example, so it's not clear to me that there is much value to pushing for a bug fix here. The code should be fixed to avoid unconstrained array parameters and results unless there is no chance that it will ever be used on a different Ada compiler (including a newer version of GNAT, which could change how this is handled). Randy. ^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2008-09-06 3:03 UTC | newest] Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-08-28 7:28 Possible compiler bug with this simple program Jerry 2008-08-28 7:56 ` Ludovic Brenta 2008-08-28 21:08 ` Jerry 2008-08-29 20:39 ` Ludovic Brenta 2008-08-29 21:20 ` Jerry 2008-08-29 21:31 ` Jerry 2008-09-02 22:10 ` Santiago Urueña 2008-08-28 8:03 ` Niklas Holsti 2008-08-28 15:54 ` Adam Beneschan 2008-08-28 15:56 ` Adam Beneschan 2008-08-28 21:01 ` Randy Brukardt 2008-08-28 21:29 ` Jerry 2008-08-30 1:00 ` Randy Brukardt 2008-08-30 4:47 ` Jerry 2008-09-01 11:19 ` Jerry 2008-09-03 4:22 ` Jerry 2008-09-03 14:20 ` Adam Beneschan 2008-09-04 0:22 ` Jerry 2008-09-04 1:18 ` Adam Beneschan 2008-09-04 3:53 ` Randy Brukardt 2008-09-04 1:31 ` Jeffrey R. Carter 2008-09-04 14:35 ` Adam Beneschan 2008-09-04 14:42 ` Jacob Sparre Andersen 2008-09-06 3:03 ` Jerry 2008-09-05 8:17 ` Ludovic Brenta 2008-09-05 15:56 ` Adam Beneschan 2008-09-05 17:09 ` Jeffrey R. Carter 2008-09-04 20:49 ` Simon Wright 2008-08-28 21:16 ` Jerry 2008-08-29 7:41 ` Niklas Holsti 2008-08-30 0:50 ` Randy Brukardt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox