* storage error: stack overflow @ 2015-08-11 21:53 hreba 2015-08-11 22:19 ` Jeffrey R. Carter ` (4 more replies) 0 siblings, 5 replies; 42+ messages in thread From: hreba @ 2015-08-11 21:53 UTC (permalink / raw) I am developing a program on 3 computers in parallel (depending on where I am). On 2 of them the executable works as expected, on one I get: raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or erroneous memory access) The computers are: a) a 32 bit desktop PC running Windows 7 b) a 32 bit desktop PC running LinuxMint release 13 c) a 64 bit Notebook running LinuxMint release 17.1 It is machine c) which makes the trouble. On each machine I compile the program (no warnings) with gnat/GPS. How can I find out what is wrong? -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-11 21:53 storage error: stack overflow hreba @ 2015-08-11 22:19 ` Jeffrey R. Carter 2015-08-12 15:01 ` hreba 2015-08-12 8:27 ` briot.emmanuel ` (3 subsequent siblings) 4 siblings, 1 reply; 42+ messages in thread From: Jeffrey R. Carter @ 2015-08-11 22:19 UTC (permalink / raw) On 08/11/2015 02:53 PM, hreba wrote: > I am developing a program on 3 computers in parallel (depending on where I am). > On 2 of them the executable works as expected, on one I get: > > raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or > erroneous memory access) > > The computers are: > > a) a 32 bit desktop PC running Windows 7 > b) a 32 bit desktop PC running LinuxMint release 13 > c) a 64 bit Notebook running LinuxMint release 17.1 > > It is machine c) which makes the trouble. > On each machine I compile the program (no warnings) with gnat/GPS. > > How can I find out what is wrong? Are you running 32- or 64-bit Linux Mint on machine C? Have you examined all your overridings of Adjust and Finalize for controlled types for something that might use a lot of stack memory or do an erroneous memory access? -- Jeff Carter "I'm a vicious jungle beast!" Play It Again, Sam 131 ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-11 22:19 ` Jeffrey R. Carter @ 2015-08-12 15:01 ` hreba 2015-08-12 16:00 ` AdaMagica 2015-08-12 17:51 ` Jeffrey R. Carter 0 siblings, 2 replies; 42+ messages in thread From: hreba @ 2015-08-12 15:01 UTC (permalink / raw) On 08/11/2015 07:19 PM, Jeffrey R. Carter wrote: > On 08/11/2015 02:53 PM, hreba wrote: >> I am developing a program on 3 computers in parallel (depending on where I am). >> On 2 of them the executable works as expected, on one I get: >> >> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or >> erroneous memory access) >> >> The computers are: >> >> a) a 32 bit desktop PC running Windows 7 >> b) a 32 bit desktop PC running LinuxMint release 13 >> c) a 64 bit Notebook running LinuxMint release 17.1 >> >> It is machine c) which makes the trouble. >> On each machine I compile the program (no warnings) with gnat/GPS. >> >> How can I find out what is wrong? > > Are you running 32- or 64-bit Linux Mint on machine C? > > Have you examined all your overridings of Adjust and Finalize for controlled > types for something that might use a lot of stack memory or do an erroneous > memory access? > I am running 64-bit LinuxMint. I don't override Adjust and Finalize. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-12 15:01 ` hreba @ 2015-08-12 16:00 ` AdaMagica 2015-08-12 17:51 ` Jeffrey R. Carter 1 sibling, 0 replies; 42+ messages in thread From: AdaMagica @ 2015-08-12 16:00 UTC (permalink / raw) Am Mittwoch, 12. August 2015 17:02:01 UTC+2 schrieb hreba: > I am running 64-bit LinuxMint. > I don't override Adjust and Finalize. Then they do nothing. If you have to deallocate storage, you must override Finalize. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-12 15:01 ` hreba 2015-08-12 16:00 ` AdaMagica @ 2015-08-12 17:51 ` Jeffrey R. Carter 2015-08-13 2:17 ` hreba 1 sibling, 1 reply; 42+ messages in thread From: Jeffrey R. Carter @ 2015-08-12 17:51 UTC (permalink / raw) On 08/12/2015 08:01 AM, hreba wrote: >>> >>> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or >>> erroneous memory access) > > I am running 64-bit LinuxMint. > I don't override Adjust and Finalize. That makes life interesting. Are you using the same version of GNAT on all the machines? Are you compiling with -fstack-check? -- Jeff Carter "Oh Lord, bless this thy hand grenade, that with it thou mayst blow thine enemies to tiny bits, in thy mercy." Monty Python and the Holy Grail 24 ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-12 17:51 ` Jeffrey R. Carter @ 2015-08-13 2:17 ` hreba 0 siblings, 0 replies; 42+ messages in thread From: hreba @ 2015-08-13 2:17 UTC (permalink / raw) On 08/12/2015 02:51 PM, Jeffrey R. Carter wrote: > On 08/12/2015 08:01 AM, hreba wrote: >>>> >>>> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or >>>> erroneous memory access) >> >> I am running 64-bit LinuxMint. >> I don't override Adjust and Finalize. > > That makes life interesting. Are you using the same version of GNAT on all the > machines? Are you compiling with -fstack-check? > GNAT version 4.6 on both Linux machines. I hadn't compiled with -fstack-check. Now I did. Nothing changed. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-11 21:53 storage error: stack overflow hreba 2015-08-11 22:19 ` Jeffrey R. Carter @ 2015-08-12 8:27 ` briot.emmanuel 2015-08-13 1:34 ` hreba 2015-08-12 10:31 ` Markus Schöpflin ` (2 subsequent siblings) 4 siblings, 1 reply; 42+ messages in thread From: briot.emmanuel @ 2015-08-12 8:27 UTC (permalink / raw) Since the problem occurs on linux, run your executable with valgrind. It will help a lot identifying the issue. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-12 8:27 ` briot.emmanuel @ 2015-08-13 1:34 ` hreba 2015-08-13 2:53 ` Jeffrey R. Carter ` (2 more replies) 0 siblings, 3 replies; 42+ messages in thread From: hreba @ 2015-08-13 1:34 UTC (permalink / raw) On 08/12/2015 05:27 AM, briot.emmanuel@gmail.com wrote: > Since the problem occurs on linux, run your executable with valgrind. It will help a lot identifying the issue. > My first contact with valgrind. Executed it as described in the Quick Start Guide with valgrind --leak-check=yes ./sos The valgrind's response starts as follows: ----------------------------------------------------------------- ==4823== Memcheck, a memory error detector ==4823== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==4823== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==4823== Command: ./sos ==4823== (process:4823): Gtk-WARNING **: Locale not supported by C library. Using the fallback 'C' locale. ==4823== Invalid read of size 4 ==4823== at 0x66FF1A0: ada__strings__unbounded__reference (in /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) ==4823== by 0x6703851: ada__strings__unbounded___assign__2 (in /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) ==4823== by 0x425FE5: surfaces__deep_copy_base (surfaces.adb:12) ==4823== by 0x426076: surfaces__deep_copy__2 (surfaces.adb:28) ==4823== by 0x428081: detectors__deep_copy__2 (detectors.adb:40) ==4823== by 0x42D936: setups__define_setup (setups.adb:43) ==4823== by 0x43E5F3: main_gui__initialize (main_gui.adb:73) ==4823== by 0x43FEBC: main_proc__data_handlers__marshallers__void_marshaller__call.4284 (gtk-marshallers.adb:1111) ==4823== by 0x441482: main_proc__data_handlers__first_marshaller.4777 (gtk-handlers.adb:1280) ==4823== by 0x5E3E3B7: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0) ==4823== by 0x5E4FD3C: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0) ==4823== by 0x5E57A28: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0) ==4823== Address 0x4 is not stack'd, malloc'd or (recently) free'd ==4823== ==4823== Warning: client switching stacks? SP change: 0x6ad0d40 --> 0xffeffed18 ==4823== to suppress, use: --max-stackframe=68590690264 or greater raised PROGRAM_ERROR : adjust/finalize raised STORAGE_ERROR: stack overflow (or erroneous memory access) ---------------------------------------------------------------- I didn't read the following 330kB of output about memory losses line by line, but most of them are related to libgobject and libgtk. The referenced line of my program surfaces.adb:12 is dest.name := source.name; These record fields are declared as UBString which is defined as subtype UBString is Ada.Strings.Unbounded.Unbounded_String; So it seems that assigning unbounded strings can be a problem. By the way, I use the gnat version from the regular repository of my LinuxMint distribution, which is 4.6. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-13 1:34 ` hreba @ 2015-08-13 2:53 ` Jeffrey R. Carter 2015-08-13 7:05 ` Simon Wright 2015-08-13 7:19 ` Simon Wright 2 siblings, 0 replies; 42+ messages in thread From: Jeffrey R. Carter @ 2015-08-13 2:53 UTC (permalink / raw) On 08/12/2015 06:34 PM, hreba wrote: > > The referenced line of my program surfaces.adb:12 is > dest.name := source.name; > These record fields are declared as UBString which is defined as > subtype UBString is Ada.Strings.Unbounded.Unbounded_String; > So it seems that assigning unbounded strings can be a problem. Interesting. I've done plenty of assigning of unbounded strings without encountering this. -- Jeff Carter "Oh Lord, bless this thy hand grenade, that with it thou mayst blow thine enemies to tiny bits, in thy mercy." Monty Python and the Holy Grail 24 ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-13 1:34 ` hreba 2015-08-13 2:53 ` Jeffrey R. Carter @ 2015-08-13 7:05 ` Simon Wright 2015-08-14 13:53 ` hreba 2015-08-13 7:19 ` Simon Wright 2 siblings, 1 reply; 42+ messages in thread From: Simon Wright @ 2015-08-13 7:05 UTC (permalink / raw) hreba <f_hreba@yahoo.com.br> writes: > ==4823== at 0x66FF1A0: ada__strings__unbounded__reference (in > /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) > ==4823== by 0x6703851: ada__strings__unbounded___assign__2 (in > /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) > ==4823== by 0x425FE5: surfaces__deep_copy_base (surfaces.adb:12) If you built your program with -g it should have linked with the static version of the libraries rather than the dynamic one, which would probably have been able to provide line number information within libgnat. Is it possible you don't have libgnat.a installed? Is there some -dev version of the libraries that you don't have? (I don't know Debian-based systems well). ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-13 7:05 ` Simon Wright @ 2015-08-14 13:53 ` hreba 2015-08-14 16:01 ` Simon Wright 2015-08-14 17:00 ` Simon Wright 0 siblings, 2 replies; 42+ messages in thread From: hreba @ 2015-08-14 13:53 UTC (permalink / raw) On 08/13/2015 04:05 AM, Simon Wright wrote: > hreba <f_hreba@yahoo.com.br> writes: > >> ==4823== at 0x66FF1A0: ada__strings__unbounded__reference (in >> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) >> ==4823== by 0x6703851: ada__strings__unbounded___assign__2 (in >> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) >> ==4823== by 0x425FE5: surfaces__deep_copy_base (surfaces.adb:12) > > If you built your program with -g it should have linked with the static > version of the libraries rather than the dynamic one, which would > probably have been able to provide line number information within > libgnat. Is it possible you don't have libgnat.a installed? Is there > some -dev version of the libraries that you don't have? (I don't know > Debian-based systems well). > All project files have "-g" as Compiler switch. One imported project file has it additionally as builder and linker switch. Makes it a difference? The installed files from libgnat are /usr /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/libgnarl-4.6.so.1 /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1 /usr/share /usr/share/doc /usr/share/doc/libgnat-4.6 /usr/share/lintian /usr/share/lintian/overrides /usr/share/lintian/overrides/libgnat-4.6 So there are only dynamic libraries. 'find /usr -name libgnat.a' found /usr/lib/gcc/x86_64-linux-gnu/4.6/rts-native/adalib/libgnat.a but I don't know where this comes from (perhaps I tried AdaCore earlier, I don't remember) and if this directory is being searched. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-14 13:53 ` hreba @ 2015-08-14 16:01 ` Simon Wright 2015-08-14 17:00 ` Simon Wright 1 sibling, 0 replies; 42+ messages in thread From: Simon Wright @ 2015-08-14 16:01 UTC (permalink / raw) hreba <f_hreba@yahoo.com.br> writes: > All project files have "-g" as Compiler switch. One imported project > file has it additionally as builder and linker switch. Makes it a > difference? Should be a Builder switch, so it gets applied in all the packages that need it; I'm pretty sure the Binder needs to see it as well as the Linker (and, for your code of course) the Compiler. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-14 13:53 ` hreba 2015-08-14 16:01 ` Simon Wright @ 2015-08-14 17:00 ` Simon Wright 1 sibling, 0 replies; 42+ messages in thread From: Simon Wright @ 2015-08-14 17:00 UTC (permalink / raw) hreba <f_hreba@yahoo.com.br> writes: > So there are only dynamic libraries. 'find /usr -name libgnat.a' found > /usr/lib/gcc/x86_64-linux-gnu/4.6/rts-native/adalib/libgnat.a > but I don't know where this comes from (perhaps I tried AdaCore > earlier, I don't remember) and if this directory is being searched. I have wheezy (Debian 7) installed, and find $ dpkg -S libgnat.a gnat-4.6: /usr/lib/gcc/x86_64-linux-gnu/4.6/rts-native/adalib/libgnat.a i.e. what you have is part of the standard 4.6 package, and linking with -g should pick it up. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-13 1:34 ` hreba 2015-08-13 2:53 ` Jeffrey R. Carter 2015-08-13 7:05 ` Simon Wright @ 2015-08-13 7:19 ` Simon Wright 2015-08-14 13:20 ` hreba 2 siblings, 1 reply; 42+ messages in thread From: Simon Wright @ 2015-08-13 7:19 UTC (permalink / raw) hreba <f_hreba@yahoo.com.br> writes: > ==4823== Invalid read of size 4 > ==4823== at 0x66FF1A0: ada__strings__unbounded__reference (in > /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) > ==4823== by 0x6703851: ada__strings__unbounded___assign__2 (in > /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) There's no Assign in the code of Ada.Strings.Unbounded, so I expect it's a subprogram generated by the compiler to manage assignment. It could be from the finalize of the 'dest' object prior to assignment, but I think it's from the adjust after the bitwise copy of the 'source' object; Adjust does contain a call to Reference. Given that, is it possible that something has corrupted the 'source' object? (at least 'source.name') ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-13 7:19 ` Simon Wright @ 2015-08-14 13:20 ` hreba 0 siblings, 0 replies; 42+ messages in thread From: hreba @ 2015-08-14 13:20 UTC (permalink / raw) On 08/13/2015 04:19 AM, Simon Wright wrote: > hreba <f_hreba@yahoo.com.br> writes: > >> ==4823== Invalid read of size 4 >> ==4823== at 0x66FF1A0: ada__strings__unbounded__reference (in >> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) >> ==4823== by 0x6703851: ada__strings__unbounded___assign__2 (in >> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1) > > There's no Assign in the code of Ada.Strings.Unbounded, so I expect it's > a subprogram generated by the compiler to manage assignment. > > It could be from the finalize of the 'dest' object prior to assignment, > but I think it's from the adjust after the bitwise copy of the 'source' > object; Adjust does contain a call to Reference. > > Given that, is it possible that something has corrupted the 'source' > object? (at least 'source.name') > The statement dest.name := source.name; is the first line in the body of the subprogram procedure Deep_Copy_Base (source: Surface; dest: in out Surface'Class); Setting a breakpoint at this subprogram, "p source" gets me $1 = (name => (prev => 0x0, next => 0x0, reference => 0x0), dist => 0.0, zabs => 1500.0, zmin => 0.0, zmax => 0.0, ap => 0x722a90) and on the other Linux machine, without the error, I get $1 = (name => (prev => 0x0, next => 0x0, reference => 0xf22b98, last => 0), dist => 0.0, zabs => 1500.0, zmin => 0.0, zmax => 0.0, ap => 0x8126b80) The value of source.name comes from a call of 'To_Unbounded_String("")'. The null reference is strange. I made a simple test program with 2 variables a, b of type 'Unbounded_String' and an assignment and it worked. After assigning the empty string to a its value is $1 = (prev => 0x0, next => 0x0, reference => 0x7ffff7dca6a0)<ada.strings.unbounded.empty_shared_string>) I reinstalled GNAT, GPS and GtkAda from the Ubuntu repository and nothing changed. I'll continue my investigation when I have more time. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-11 21:53 storage error: stack overflow hreba 2015-08-11 22:19 ` Jeffrey R. Carter 2015-08-12 8:27 ` briot.emmanuel @ 2015-08-12 10:31 ` Markus Schöpflin 2015-08-13 1:36 ` hreba 2015-08-12 10:57 ` Simon Wright 2015-08-18 2:16 ` hreba 4 siblings, 1 reply; 42+ messages in thread From: Markus Schöpflin @ 2015-08-12 10:31 UTC (permalink / raw) Additionally to the other suggestions you should check with 'ulimit -s' if your stack size is limited on the machine where your Ada program acts up. I think that Linux Mint by default has a stack size limit of 8MB. HTH, Markus ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-12 10:31 ` Markus Schöpflin @ 2015-08-13 1:36 ` hreba 0 siblings, 0 replies; 42+ messages in thread From: hreba @ 2015-08-13 1:36 UTC (permalink / raw) On 08/12/2015 07:31 AM, Markus Schöpflin wrote: > Additionally to the other suggestions you should check with 'ulimit -s' > if your stack size is limited on the machine where your Ada program acts > up. > > I think that Linux Mint by default has a stack size limit of 8MB. > > HTH, > Markus Correct. On both Linux machines the response is 8192. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-11 21:53 storage error: stack overflow hreba ` (2 preceding siblings ...) 2015-08-12 10:31 ` Markus Schöpflin @ 2015-08-12 10:57 ` Simon Wright 2015-08-13 0:55 ` hreba 2015-08-18 2:16 ` hreba 4 siblings, 1 reply; 42+ messages in thread From: Simon Wright @ 2015-08-12 10:57 UTC (permalink / raw) hreba <f_hreba@yahoo.com.br> writes: > I am developing a program on 3 computers in parallel (depending on > where I am). On 2 of them the executable works as expected, on one I > get: > > raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack > overflow (or erroneous memory access) > How can I find out what is wrong? Use the debugger and 'catch exception storage_error'? I'd think it's more likely an erroneous memory access than a stack overflow. As I remember, GNAT catches a SIGSEGV and does its best to work out what the problem was, but at that level it can be hard to tell. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-12 10:57 ` Simon Wright @ 2015-08-13 0:55 ` hreba 2015-08-13 6:58 ` Simon Wright 0 siblings, 1 reply; 42+ messages in thread From: hreba @ 2015-08-13 0:55 UTC (permalink / raw) On 08/12/2015 07:57 AM, Simon Wright wrote: > hreba <f_hreba@yahoo.com.br> writes: > >> I am developing a program on 3 computers in parallel (depending on >> where I am). On 2 of them the executable works as expected, on one I >> get: >> >> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack >> overflow (or erroneous memory access) > >> How can I find out what is wrong? > > Use the debugger and 'catch exception storage_error'? > > I'd think it's more likely an erroneous memory access than a stack > overflow. As I remember, GNAT catches a SIGSEGV and does its best to > work out what the problem was, but at that level it can be hard to tell. > The name of my program is "sos". Calling it with gdb: ----------------------------------------------------- ~/Projects/SOS/Exec $ gdb sos <some infos about gdb> Reading symbols from sos...done (gdb) catch exception storage_error Unable to insert catchpoint. Try to start the program first. (gdb) run Starting program: /home/frank/Projects/SOS/Exec/sos [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1" (process:2365): Gtk-WARNING **: Locale not supported by C library. Using the fallback 'C' locale Program received signal SIGSEGV, segmentation fault. 0x00007ffff627a1a0 in ada.strings.unbounded.reference () from /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1 (gdb) catch exception storage_error Your Ada runtime appears to be missing some debug information. Cannot insert Ada exception catchpoint in this configuration. --------------------------------------------------------- I compiled my program for debugging, but the debug information perhaps is missing in libgnat. Anyway, the problem has to do with Ada.Strings.Unbounded. For more, see my answer to Emmanuel Briot. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-13 0:55 ` hreba @ 2015-08-13 6:58 ` Simon Wright 0 siblings, 0 replies; 42+ messages in thread From: Simon Wright @ 2015-08-13 6:58 UTC (permalink / raw) hreba <f_hreba@yahoo.com.br> writes: > (gdb) catch exception storage_error > Your Ada runtime appears to be missing some debug information. > Cannot insert Ada exception catchpoint in this configuration. I wrote about something similar at [1]. The workround there was to say, in gdb, (gdb) print __gnat_debug_raise_exception which managed to find and cache the symbol that 'catch exception' was looking for, after which 'catch exception' worked. [1] http://forward-in-code.blogspot.co.uk/2012/01/catching-exceptions-in-gdb.html ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-11 21:53 storage error: stack overflow hreba ` (3 preceding siblings ...) 2015-08-12 10:57 ` Simon Wright @ 2015-08-18 2:16 ` hreba 2015-08-18 5:49 ` Jeffrey R. Carter 2015-08-18 7:24 ` Egil H H 4 siblings, 2 replies; 42+ messages in thread From: hreba @ 2015-08-18 2:16 UTC (permalink / raw) On 08/11/2015 06:53 PM, hreba wrote: > I am developing a program on 3 computers in parallel (depending on where > I am). On 2 of them the executable works as expected, on one I get: > > raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack > overflow (or erroneous memory access) > > The computers are: > > a) a 32 bit desktop PC running Windows 7 > b) a 32 bit desktop PC running LinuxMint release 13 > c) a 64 bit Notebook running LinuxMint release 17.1 > > It is machine c) which makes the trouble. > On each machine I compile the program (no warnings) with gnat/GPS. > > How can I find out what is wrong? Replying to my own post: With your help I was able to localize the error. Now I wrote a simple test program which behaves as the original one: runs on the machines a) and b) and provokes the error on c). Here it is: with Ada.Strings.Unbounded; procedure testUBS is type TA is record name: Ada.Strings.Unbounded.Unbounded_String; end record; type TB is record a: TA; end record; function New_TB (name: String:="") return access TB is begin return new TB' (a=>TA'(name=>Ada.Strings.Unbounded.To_Unbounded_String(name))); end New_TB; b: access TB:= New_TB (name=>"Det"); name: Ada.Strings.Unbounded.Unbounded_String; begin name:= b.a.name; end testUBS; -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 2:16 ` hreba @ 2015-08-18 5:49 ` Jeffrey R. Carter 2015-08-18 7:24 ` Egil H H 1 sibling, 0 replies; 42+ messages in thread From: Jeffrey R. Carter @ 2015-08-18 5:49 UTC (permalink / raw) On 08/17/2015 07:16 PM, hreba wrote: > > with Ada.Strings.Unbounded; > > procedure testUBS is > > type TA is record > name: Ada.Strings.Unbounded.Unbounded_String; > end record; > > type TB is record > a: TA; > end record; > > function New_TB (name: String:="") return access TB is > begin > return new TB' > (a=>TA'(name=>Ada.Strings.Unbounded.To_Unbounded_String(name))); > end New_TB; > > b: access TB:= New_TB (name=>"Det"); > name: Ada.Strings.Unbounded.Unbounded_String; > > begin > name:= b.a.name; > end testUBS; This works fine on my 64-bit Linux (LMDE2) with the default compiler (GNAT 4.9.2). -- Jeff Carter "I wave my private parts at your aunties." Monty Python & the Holy Grail 13 ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 2:16 ` hreba 2015-08-18 5:49 ` Jeffrey R. Carter @ 2015-08-18 7:24 ` Egil H H 2015-08-18 12:23 ` hreba 1 sibling, 1 reply; 42+ messages in thread From: Egil H H @ 2015-08-18 7:24 UTC (permalink / raw) On Tuesday, August 18, 2015 at 4:16:38 AM UTC+2, hreba wrote: > > with Ada.Strings.Unbounded; > > procedure testUBS is > > type TA is record > name: Ada.Strings.Unbounded.Unbounded_String; > end record; > > type TB is record > a: TA; > end record; > > function New_TB (name: String:="") return access TB is > begin > return new TB' > (a=>TA'(name=>Ada.Strings.Unbounded.To_Unbounded_String(name))); > end New_TB; > > b: access TB:= New_TB (name=>"Det"); > name: Ada.Strings.Unbounded.Unbounded_String; > > begin > name:= b.a.name; > end testUBS; > This fails as described with Gnat Pro 6.4.1 (GCC 4.5.2), but seems to be fixed in later versions, at least Gnat Pro 7.1.1 (GCC 4.7.3). You should try to avoid anonymous access types if at all possible. However, you could try to work around the problem using an extended return, like this: function New_TB (Name : String := "") return access TB is begin return Foo : access TB := new TB do foo.all := TB' (A => TA' (Name => Ada.Strings.Unbounded.To_Unbounded_String(Name))); end return; end New_TB; ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 7:24 ` Egil H H @ 2015-08-18 12:23 ` hreba 2015-08-18 12:37 ` Jacob Sparre Andersen ` (2 more replies) 0 siblings, 3 replies; 42+ messages in thread From: hreba @ 2015-08-18 12:23 UTC (permalink / raw) On 08/18/2015 04:24 AM, Egil H H wrote: > On Tuesday, August 18, 2015 at 4:16:38 AM UTC+2, hreba wrote: >> >> with Ada.Strings.Unbounded; >> >> procedure testUBS is >> >> type TA is record >> name: Ada.Strings.Unbounded.Unbounded_String; >> end record; >> >> type TB is record >> a: TA; >> end record; >> >> function New_TB (name: String:="") return access TB is >> begin >> return new TB' >> (a=>TA'(name=>Ada.Strings.Unbounded.To_Unbounded_String(name))); >> end New_TB; >> >> b: access TB:= New_TB (name=>"Det"); >> name: Ada.Strings.Unbounded.Unbounded_String; >> >> begin >> name:= b.a.name; >> end testUBS; >> > > This fails as described with Gnat Pro 6.4.1 (GCC 4.5.2), > but seems to be fixed in later versions, at least Gnat Pro 7.1.1 (GCC 4.7.3). > > You should try to avoid anonymous access types if at all possible. I need an access type because in my real program TB is a tagged type and I need class-wide variables. As long as everything works I prefer the anonymous type because it saves me a type conversion. But I am still in doubt about the best practice, there is some discrepancy between the examples in my Ada book (Barnes) and the posts in this group. > However, you could try to work around the problem using an extended return, > like this: > > function New_TB > (Name : String := "") > return access TB > is > begin > return Foo : access TB := new TB do > foo.all := TB' > (A => TA' > (Name => Ada.Strings.Unbounded.To_Unbounded_String(Name))); > end return; > end New_TB; > Didn't know about extended return (the Ada 95 book was cheaper -:). But there is a problem: the TB in my original program is not only tagged, it is limited too (and New_TB is for initialization). So "foo.all:=..." is forbidden. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 12:23 ` hreba @ 2015-08-18 12:37 ` Jacob Sparre Andersen 2015-08-18 14:02 ` hreba 2015-08-18 14:15 ` Egil H H 2015-08-18 14:16 ` Jeffrey R. Carter 2 siblings, 1 reply; 42+ messages in thread From: Jacob Sparre Andersen @ 2015-08-18 12:37 UTC (permalink / raw) hreba <f_hreba@yahoo.com.br> writes: > I need an access type because in my real program TB is a tagged type > and I need class-wide variables. This is generally not a reason to use access types in Ada. Greetings, Jacob -- "Don't get me wrong, perl is an OK operating system, but it lacks a lightweight scripting language." ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 12:37 ` Jacob Sparre Andersen @ 2015-08-18 14:02 ` hreba 2015-08-18 14:11 ` Dmitry A. Kazakov 2015-08-18 14:16 ` Jeffrey R. Carter 0 siblings, 2 replies; 42+ messages in thread From: hreba @ 2015-08-18 14:02 UTC (permalink / raw) On 08/18/2015 09:37 AM, Jacob Sparre Andersen wrote: > hreba <f_hreba@yahoo.com.br> writes: > >> I need an access type because in my real program TB is a tagged type >> and I need class-wide variables. > > This is generally not a reason to use access types in Ada. > > Greetings, > > Jacob > Huh? As much as I know you cannot declare variables of a type with unknown storage requirements at compile time, such as class-wide types and arrays with unknown range. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 14:02 ` hreba @ 2015-08-18 14:11 ` Dmitry A. Kazakov 2015-08-18 14:16 ` Jeffrey R. Carter 1 sibling, 0 replies; 42+ messages in thread From: Dmitry A. Kazakov @ 2015-08-18 14:11 UTC (permalink / raw) On Tue, 18 Aug 2015 11:02:40 -0300, hreba wrote: > On 08/18/2015 09:37 AM, Jacob Sparre Andersen wrote: >> hreba <f_hreba@yahoo.com.br> writes: >> >>> I need an access type because in my real program TB is a tagged type >>> and I need class-wide variables. >> >> This is generally not a reason to use access types in Ada. > Huh? As much as I know you cannot declare variables of a type with > unknown storage requirements at compile time, such as class-wide types > and arrays with unknown range. Of course you can, e.g. declare Line : String := Get_Line; begin ... -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 14:02 ` hreba 2015-08-18 14:11 ` Dmitry A. Kazakov @ 2015-08-18 14:16 ` Jeffrey R. Carter 2015-08-18 20:56 ` Randy Brukardt 2015-08-19 1:48 ` hreba 1 sibling, 2 replies; 42+ messages in thread From: Jeffrey R. Carter @ 2015-08-18 14:16 UTC (permalink / raw) On 08/18/2015 07:02 AM, hreba wrote: > > Huh? As much as I know you cannot declare variables of a type with unknown > storage requirements at compile time, such as class-wide types and arrays with > unknown range. These are "indefinite types". You can declare an object of an indefinite type as long as you supply an initialization expression: S : String := "Hello"; V : T'Class := Some_Function; -- Jeff Carter "Blessed are they who convert their neighbors' oxen, for they shall inhibit their girth." Monty Python's Life of Brian 83 ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 14:16 ` Jeffrey R. Carter @ 2015-08-18 20:56 ` Randy Brukardt 2015-08-19 1:48 ` hreba 1 sibling, 0 replies; 42+ messages in thread From: Randy Brukardt @ 2015-08-18 20:56 UTC (permalink / raw) "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message news:mqvejr$hai$2@dont-email.me... > On 08/18/2015 07:02 AM, hreba wrote: >> >> Huh? As much as I know you cannot declare variables of a type with >> unknown >> storage requirements at compile time, such as class-wide types and arrays >> with >> unknown range. > > These are "indefinite types". You can declare an object of an indefinite > type as > long as you supply an initialization expression: > > S : String := "Hello"; > > V : T'Class := Some_Function; And if you need to change the type of the object after initialization, you can use the "Holder" container, which exists for this very purpose: package T_Class_Holder is new Ada.Containers.Indefinite_Holders (T'Class); V : T_Class_Holder.Holder; begin V.Replace_Element (Some_Function); ... V.Replace_Element (Some_Other_Function); ... end; In Ada 2012, you can also use the reference function to modify the object, but you can't change the tag that way. That is: V.Reference := Some_Function; As noted, this will raise Constraint_Error if the tag of V.Reference is changed. I may sound like a broken record (scratched CD?? ;-), but using a Holder rather than explicit access types lets the library do the storage management rather than the programmer. There are much less likely to be bugs that way. And of course, you can do this with all of the containers; if you need a Map or Tree or Vector [including an array] of T'Class, just instantiate the appropriate container and again let someone at your compiler vendor get the storage management right, rather than doing it yourself. Randy. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 14:16 ` Jeffrey R. Carter 2015-08-18 20:56 ` Randy Brukardt @ 2015-08-19 1:48 ` hreba 2015-08-19 5:10 ` Jeffrey R. Carter ` (2 more replies) 1 sibling, 3 replies; 42+ messages in thread From: hreba @ 2015-08-19 1:48 UTC (permalink / raw) On 08/18/2015 11:16 AM, Jeffrey R. Carter wrote: > On 08/18/2015 07:02 AM, hreba wrote: >> >> Huh? As much as I know you cannot declare variables of a type with unknown >> storage requirements at compile time, such as class-wide types and arrays with >> unknown range. > > These are "indefinite types". You can declare an object of an indefinite type as > long as you supply an initialization expression: > > S : String := "Hello"; > > V : T'Class := Some_Function; > If the object is initialized, the storage requirement is known at compile type. My situation is a typical object orientation case as shown in a lot of examples where you have a (possibly abstract) base type and several extensions and where the dynamic type of a variable is not known at compile time. Classic example would be an inhomogeneous list (I know in practice you use a container for that, it is just an example). My knowledge of Ada exceeds Ada 95 only by very little but I am pretty sure that in such a case one uses variables of a class-wide type, and as one cannot initialize them one has to declare them as access types. Or, if I am wrong, what would be the best practice for that? -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-19 1:48 ` hreba @ 2015-08-19 5:10 ` Jeffrey R. Carter 2015-08-19 8:44 ` Georg Bauhaus 2015-08-19 20:53 ` Bob Duff 2 siblings, 0 replies; 42+ messages in thread From: Jeffrey R. Carter @ 2015-08-19 5:10 UTC (permalink / raw) On 08/18/2015 06:48 PM, hreba wrote: > >> V : T'Class := Some_Function; > > If the object is initialized, the storage requirement is known at compile type. > My situation is a typical object orientation case as shown in a lot of examples > where you have a (possibly abstract) base type and several extensions and where > the dynamic type of a variable is not known at compile time. Classic example > would be an inhomogeneous list (I know in practice you use a container for that, > it is just an example). > My knowledge of Ada exceeds Ada 95 only by very little but I am pretty sure that > in such a case one uses variables of a class-wide type, and as one cannot > initialize them one has to declare them as access types. > > Or, if I am wrong, what would be the best practice for that? If an object is initialized by a function call, as above, the size is not known at compile time. Consider S : String := Ada.Text_IO.Get_Line; The size of S is not known until run time. Thus it is often possible to use a normal object declaration for a value of an indefinite type not known until run time. Block statements are useful for delaying a declaration until then. As Randy pointed out, an indefinite holder can be used as a variable of a class-wide type. Holders were introduced in Ada 12, but it's easy enough to write one if you're using an earlier compiler. Your application code does not use access types in either case. You'll need to use an access type to implement an indefinite holder, but such use will be in a single place and so easier to get correct than with access values scattered throughout your application -- Jeff Carter "Blessed are they who convert their neighbors' oxen, for they shall inhibit their girth." Monty Python's Life of Brian 83 ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-19 1:48 ` hreba 2015-08-19 5:10 ` Jeffrey R. Carter @ 2015-08-19 8:44 ` Georg Bauhaus 2015-08-19 11:56 ` hreba 2015-08-19 20:53 ` Bob Duff 2 siblings, 1 reply; 42+ messages in thread From: Georg Bauhaus @ 2015-08-19 8:44 UTC (permalink / raw) On 19.08.15 03:48, hreba wrote: > My knowledge of Ada exceeds Ada 95 only by very little but I am pretty sure that in such a case one uses variables of a class-wide type, and as one cannot initialize them one has to declare them as access types. The assumption that limited objects cannot be initialized like non-limited (by sort of copying a value) is no longer true, and it wasn't the whole truth in Ada 95. There are cases when nothing but an access type will do. But due to build-in-place, limited tagged objects can be declared and initialized, by aggregate or by function call, using just traditional syntax as Jeffrey Carter explains. This includes objects of a class-wide type, Built-in-place (in situ), perhaps simplifying, means that the limited object is declared and passed/used behind the scenes, for initialization. For example, the object that is declared becomes the to-be-returned object if there is a function call after “:=” in the declaration. (See "extended return" of Ada 2005.) Given package Classwide is type T0 is abstract tagged limited null record; type T1 is new T0 with private; function Make return T1; function Produce (Variant : Boolean) return T1'Class; private type T1 is new T0 with record -- note default values for "default construction" Name : Character := '?'; end record; end Classwide; package body Classwide is type T2 is new T1 with record Count : Natural; end record; function Make return T2; function Make return T1 is begin return T1'(T0 with Name => '*'); end Make; function Make return T2 is begin return T2'(T1'(Make) with Count => 0); end Make; function Produce (Variant : Boolean) return T1'Class is begin case Variant is when False => return T1'(T0 with Name => 'T'); when True => return T2'(T0 with Name => 'F', Count => 0); end case; end Produce; end Classwide; Then, the type hierarchy above includes limited T0, T1, and invisible T2. All of these types can be used to declare or create objects of specific types and of class-wide types. with Classwide; procedure Main is use Classwide; X : T1; C : T1'Class := Make; CC : T1'Class := Produce (Variant => False); procedure Takes_T1C (Object : in T1'Class) is separate; procedure Mods_T1C (Object : in out T1'Class) is separate; begin Takes_T1C (X); Takes_T1C (C); Takes_T1C (CC); Takes_T1C (Make); Takes_T1C (Produce (Variant => True)); Mods_T1C (X); Mods_T1C (C); Mods_T1C (CC); end Main; The Ada Rationale will illustrate and explain. ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-19 8:44 ` Georg Bauhaus @ 2015-08-19 11:56 ` hreba 0 siblings, 0 replies; 42+ messages in thread From: hreba @ 2015-08-19 11:56 UTC (permalink / raw) On 08/19/2015 05:44 AM, Georg Bauhaus wrote: > On 19.08.15 03:48, hreba wrote: >> My knowledge of Ada exceeds Ada 95 only by very little but I am pretty >> sure that in such a case one uses variables of a class-wide type, and >> as one cannot initialize them one has to declare them as access types. > > The assumption that limited objects cannot be initialized like non-limited > (by sort of copying a value) is no longer true, and it wasn't the whole > truth > in Ada 95. > There are cases when nothing but an access type will do. But due > to build-in-place, limited tagged objects can be declared and initialized, > by aggregate or by function call, using just traditional syntax as > Jeffrey Carter explains. This includes objects of a class-wide type, > > Built-in-place (in situ), perhaps simplifying, means that the limited > object is declared and passed/used behind the scenes, for initialization. > For example, the object that is declared becomes the to-be-returned > object if there is a function call after “:=” in the declaration. > (See "extended return" of Ada 2005.) > > Given > > package Classwide is > > type T0 is abstract tagged limited null record; > > type T1 is new T0 with private; > function Make return T1; > > function Produce (Variant : Boolean) return T1'Class; > > private > type T1 is new T0 with > record -- note default values for "default construction" > Name : Character := '?'; > end record; > end Classwide; > > package body Classwide is > type T2 is new T1 with > record > Count : Natural; > end record; > function Make return T2; > > function Make return T1 is > begin > return T1'(T0 with Name => '*'); > end Make; > > function Make return T2 is > begin > return T2'(T1'(Make) with Count => 0); > end Make; > > function Produce (Variant : Boolean) return T1'Class is > begin > case Variant is > when False => > return T1'(T0 with Name => 'T'); > when True => > return T2'(T0 with Name => 'F', Count => 0); > end case; > end Produce; > end Classwide; > > > Then, the type hierarchy above includes limited T0, T1, and invisible T2. > All of these types can be used to declare or create objects of specific > types and of class-wide types. > > with Classwide; > procedure Main is > use Classwide; > X : T1; > C : T1'Class := Make; > CC : T1'Class := Produce (Variant => False); > procedure Takes_T1C (Object : in T1'Class) is separate; > procedure Mods_T1C (Object : in out T1'Class) is separate; > begin > Takes_T1C (X); > Takes_T1C (C); > Takes_T1C (CC); > Takes_T1C (Make); > Takes_T1C (Produce (Variant => True)); > Mods_T1C (X); > Mods_T1C (C); > Mods_T1C (CC); > end Main; > > The Ada Rationale will illustrate and explain. > Thanks for your explications Jeffrey an Georg. Apparently Barnes: "Programming in Ada 95" is obsolete with respect to this topic (not regarding correctness, just best practices). What didactic text about object oriented programming in Ada would you recommend? -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-19 1:48 ` hreba 2015-08-19 5:10 ` Jeffrey R. Carter 2015-08-19 8:44 ` Georg Bauhaus @ 2015-08-19 20:53 ` Bob Duff 2 siblings, 0 replies; 42+ messages in thread From: Bob Duff @ 2015-08-19 20:53 UTC (permalink / raw) hreba <f_hreba@yahoo.com.br> writes: > On 08/18/2015 11:16 AM, Jeffrey R. Carter wrote: >> On 08/18/2015 07:02 AM, hreba wrote: >>> >>> Huh? As much as I know you cannot declare variables of a type with unknown >>> storage requirements at compile time, such as class-wide types and arrays with >>> unknown range. >> >> These are "indefinite types". You can declare an object of an indefinite type as >> long as you supply an initialization expression: >> >> S : String := "Hello"; >> >> V : T'Class := Some_Function; >> > > If the object is initialized, the storage requirement is known at compile > type. No, as Jeff and Randy have pointed out, when you initialize an object with a call to a function that returns an indefinite subtype (such as String, or T'Class), the size of the object is determined at run time. What's more, it's determined by the function body -- it is not known in the callee until the function has returned. But that only works if you can initialize the object on its declaration. Sometimes, the declaration needs to occur at a certain place for visibility reasons, and only later is initialized. You need access types for that (possibly encapsulated in Holders, or whatever). It also doesn't work if the Tag needs to change. In the above, V'Tag is set to whatever Some_Function returns, and can never be changed. - Bob ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 12:23 ` hreba 2015-08-18 12:37 ` Jacob Sparre Andersen @ 2015-08-18 14:15 ` Egil H H 2015-08-19 13:07 ` hreba 2015-08-18 14:16 ` Jeffrey R. Carter 2 siblings, 1 reply; 42+ messages in thread From: Egil H H @ 2015-08-18 14:15 UTC (permalink / raw) > Didn't know about extended return (the Ada 95 book was cheaper -:). But > there is a problem: the TB in my original program is not only tagged, it > is limited too (and New_TB is for initialization). So "foo.all:=..." is > forbidden. > Then "foo.A :=..." ... ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 14:15 ` Egil H H @ 2015-08-19 13:07 ` hreba 0 siblings, 0 replies; 42+ messages in thread From: hreba @ 2015-08-19 13:07 UTC (permalink / raw) On 08/18/2015 11:15 AM, Egil H H wrote: > >> Didn't know about extended return (the Ada 95 book was cheaper -:). But >> there is a problem: the TB in my original program is not only tagged, it >> is limited too (and New_TB is for initialization). So "foo.all:=..." is >> forbidden. >> > > Then "foo.A :=..." > ... > Works now. Thanks for your help! -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 12:23 ` hreba 2015-08-18 12:37 ` Jacob Sparre Andersen 2015-08-18 14:15 ` Egil H H @ 2015-08-18 14:16 ` Jeffrey R. Carter 2015-08-19 13:12 ` hreba 2015-08-19 20:47 ` Bob Duff 2 siblings, 2 replies; 42+ messages in thread From: Jeffrey R. Carter @ 2015-08-18 14:16 UTC (permalink / raw) On 08/18/2015 05:23 AM, hreba wrote: > > I need an access type because in my real program TB is a tagged type and I need > class-wide variables. You do not /need/ access types for this. Avoiding them requires some thought, but that's what S/W engineers do. > Didn't know about extended return (the Ada 95 book was cheaper -:). But there is > a problem: the TB in my original program is not only tagged, it is limited too > (and New_TB is for initialization). So "foo.all:=..." is forbidden. If your type is limited then you will have to use an extended return for Ada > 95. Does return Foo : access TB := new TB'( (A => TA'(Name => To_Unbounded_String (Name) ) ); work? -- Jeff Carter "Blessed are they who convert their neighbors' oxen, for they shall inhibit their girth." Monty Python's Life of Brian 83 ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 14:16 ` Jeffrey R. Carter @ 2015-08-19 13:12 ` hreba 2015-08-19 20:47 ` Bob Duff 1 sibling, 0 replies; 42+ messages in thread From: hreba @ 2015-08-19 13:12 UTC (permalink / raw) On 08/18/2015 11:16 AM, Jeffrey R. Carter wrote: > On 08/18/2015 05:23 AM, hreba wrote: >> >> I need an access type because in my real program TB is a tagged type and I need >> class-wide variables. > > You do not /need/ access types for this. Avoiding them requires some thought, > but that's what S/W engineers do. > >> Didn't know about extended return (the Ada 95 book was cheaper -:). But there is >> a problem: the TB in my original program is not only tagged, it is limited too >> (and New_TB is for initialization). So "foo.all:=..." is forbidden. > > If your type is limited then you will have to use an extended return for Ada > > 95. Does > > return Foo : access TB := > new TB'( (A => TA'(Name => To_Unbounded_String (Name) ) ); > > work? > This got me a GNAT BUG DETECTED message upon compilation. Will follow the request to send a bug report. I am happy with Egil's workaround. Thanks for your hints and help. -- Frank Hrebabetzky +55 / 48 / 3235 1106 Florianopolis, Brazil ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-18 14:16 ` Jeffrey R. Carter 2015-08-19 13:12 ` hreba @ 2015-08-19 20:47 ` Bob Duff 2015-08-19 21:47 ` Jeffrey R. Carter 2015-08-20 20:48 ` Randy Brukardt 1 sibling, 2 replies; 42+ messages in thread From: Bob Duff @ 2015-08-19 20:47 UTC (permalink / raw) "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes: > On 08/18/2015 05:23 AM, hreba wrote: >> >> I need an access type because in my real program TB is a tagged type and I need >> class-wide variables. > > You do not /need/ access types for this. Avoiding them requires some thought, > but that's what S/W engineers do. I don't think it's fair to say that people who use access types (i.e. pointers) aren't proper "S/W engineers". It's true that Ada doesn't require pointers in many cases where other languages do. But Ada still requires pointers if the class-wide variable needs to change its tag. And pointers are required for recursive data structures. Etc. I think what you and Randy have been saying (or should have been?) is more like: 1. Try to avoid using pointers. 2. When you have to use them, try to encapsulate. 3. When possible, use the encapsulations already provided by the language (i.e. the Ada.Containers). But there are all sorts of reasons why Ada.Containers might not be suitable, so in those cases, you WILL use pointers, preferably encapsulated. But that's different from saying "never use pointers" (or "never use access types"). >> Didn't know about extended return (the Ada 95 book was cheaper -:). But there is >> a problem: the TB in my original program is not only tagged, it is limited too >> (and New_TB is for initialization). So "foo.all:=..." is forbidden. > > If your type is limited then you will have to use an extended return for Ada > > 95. ... I'm not sure what you mean by that. There is no rule that return of a limited type requires extended return. This: return expression; means exactly the same thing as: return Result : T := expression do null; end return; whether T is limited or not. You only need extended return when you want to have a name for the function result (so you can assign into parts of it, for example). And anyway, the example is returning an access value, which is not limited. > ...Does > > return Foo : access TB := > new TB'( (A => TA'(Name => To_Unbounded_String (Name) ) ); > > work? Maybe you were just hoping that the extended return version wouldn't tickle the same compiler bug? That's possible, but unlikely; I didn't try it. Anyway, that could be written: return new TB'( (A => TA'(Name => To_Unbounded_String (Name) ) ); and mean the same thing. - Bob ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-19 20:47 ` Bob Duff @ 2015-08-19 21:47 ` Jeffrey R. Carter 2015-08-20 7:18 ` Dmitry A. Kazakov 2015-08-20 20:48 ` Randy Brukardt 1 sibling, 1 reply; 42+ messages in thread From: Jeffrey R. Carter @ 2015-08-19 21:47 UTC (permalink / raw) On 08/19/2015 01:47 PM, Bob Duff wrote: > "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes: >> >> You do not /need/ access types for this. Avoiding them requires some thought, >> but that's what S/W engineers do. > > I don't think it's fair to say that people who use access types > (i.e. pointers) aren't proper "S/W engineers". It's true that Ada > doesn't require pointers in many cases where other languages do. > But Ada still requires pointers if the class-wide variable > needs to change its tag. And pointers are required for recursive > data structures. Etc. I didn't say that people who use access types aren't proper S/W engineers. I implied that people who use access types unnecessarily because they're unwilling or unable to do the extra thinking needed to avoid aren't S/W engineers. > I think what you and Randy have been saying (or should have been?) > is more like: > > 1. Try to avoid using pointers. > > 2. When you have to use them, try to encapsulate. > > 3. When possible, use the encapsulations already provided by the > language (i.e. the Ada.Containers). > > But there are all sorts of reasons why Ada.Containers might not be > suitable, so in those cases, you WILL use pointers, preferably > encapsulated. But that's different from saying "never use pointers" > (or "never use access types"). Almost. Using an abstraction that happens to be implemented using pointers is not the same as using pointers. The whole point of the abstraction is so the user doesn't have to think in the terms of its implementation. For example, when I write Ada, the compiler implements it in machine code. Ada is an abstraction that allows me to not have to think in terms of machine code. I consider it incorrect to refer to using Ada as using machine code. I also think it's incorrect to refer to using an abstraction implemented with pointers as using pointers. So I'd probably say: Before using pointers, 1. Try to use an existing abstraction that doesn't require using pointers, such as Ada.Containers. 2. If that's not possible, try to create an abstraction that encapsulates the use of pointers and doesn't require its user to use pointers. 3. If that's not possible, then see if there's anything else that will allow you to avoid using pointers. 4. If that's not possible, then use pointers. -- Jeff Carter "Alms for an ex-leper!" Monty Python's Life of Brian 75 ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-19 21:47 ` Jeffrey R. Carter @ 2015-08-20 7:18 ` Dmitry A. Kazakov 0 siblings, 0 replies; 42+ messages in thread From: Dmitry A. Kazakov @ 2015-08-20 7:18 UTC (permalink / raw) On Wed, 19 Aug 2015 14:47:41 -0700, Jeffrey R. Carter wrote: > On 08/19/2015 01:47 PM, Bob Duff wrote: >> "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes: >>> >>> You do not /need/ access types for this. Avoiding them requires some thought, >>> but that's what S/W engineers do. >> >> I don't think it's fair to say that people who use access types >> (i.e. pointers) aren't proper "S/W engineers". It's true that Ada >> doesn't require pointers in many cases where other languages do. >> But Ada still requires pointers if the class-wide variable >> needs to change its tag. And pointers are required for recursive >> data structures. Etc. > > I didn't say that people who use access types aren't proper S/W engineers. I > implied that people who use access types unnecessarily because they're unwilling > or unable to do the extra thinking needed to avoid aren't S/W engineers. Actually it is the access type which require extra thinking. I remember how hard it was to understand the meaning of C's declarations like char *argv[] I think it is rather the first language which forms the ways of thinking of future SW engineers. People coming from GC languages have no less strange ideas than ones with a C background. (Good that functional languages are not taught as massively as C and C# are (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: storage error: stack overflow 2015-08-19 20:47 ` Bob Duff 2015-08-19 21:47 ` Jeffrey R. Carter @ 2015-08-20 20:48 ` Randy Brukardt 1 sibling, 0 replies; 42+ messages in thread From: Randy Brukardt @ 2015-08-20 20:48 UTC (permalink / raw) "Bob Duff" <bobduff@theworld.com> wrote in message news:87k2srf1j8.fsf@theworld.com... > "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes: > >> On 08/18/2015 05:23 AM, hreba wrote: >>> >>> I need an access type because in my real program TB is a tagged type and >>> I need >>> class-wide variables. >> >> You do not /need/ access types for this. Avoiding them requires some >> thought, >> but that's what S/W engineers do. > > I don't think it's fair to say that people who use access types > (i.e. pointers) aren't proper "S/W engineers". It's true that Ada > doesn't require pointers in many cases where other languages do. > But Ada still requires pointers if the class-wide variable > needs to change its tag. And pointers are required for recursive > data structures. Etc. > > I think what you and Randy have been saying (or should have been?) > is more like: > > 1. Try to avoid using pointers. > > 2. When you have to use them, try to encapsulate. > > 3. When possible, use the encapsulations already provided by the > language (i.e. the Ada.Containers). > > But there are all sorts of reasons why Ada.Containers might not be > suitable, so in those cases, you WILL use pointers, preferably > encapsulated. But that's different from saying "never use pointers" > (or "never use access types"). I say "never* use access types in the visible part of a package specification". And do what you have to implement that specification. Bodies of any good abstraction tend to turn into a groddy mess (especially once performance considerations get into the mix). That doesn't mean that the specification (the interface) of the abstract has to also be a groddy mess! The problem with putting access types in a specification is that you are then dictating how the client does storage management (they can no longer let a container or other abstraction do the management for them). That's the worst possible situation, letting the client decide on the optimal storage management for their uses is preferable, and the alternative of managing the storage within the abstraction is likely better as well. * As with all programming rules, there never is an absolute rule. There probably is some case where putting an access type into a specification would be better than trying to work around it. If you have a strong justification for doing so (one that does not appeal to knowledge of some other programming language!!), then go ahead (and document the reasoning). We had to use one in Claw because we needed a version of the Parent function that had reference semantics for its return. (I recall that without that, some operation became an infinite regress of copying.) I agonized about that for weeks, but couldn't find a better solution. (The solution ended up being an encapsulated access value that was part of inspiration for generalized references and how they're used in the containers. We could have done that a lot better in Ada 2012, but there still would be an access type.) Randy. ^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2015-08-20 20:48 UTC | newest] Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-08-11 21:53 storage error: stack overflow hreba 2015-08-11 22:19 ` Jeffrey R. Carter 2015-08-12 15:01 ` hreba 2015-08-12 16:00 ` AdaMagica 2015-08-12 17:51 ` Jeffrey R. Carter 2015-08-13 2:17 ` hreba 2015-08-12 8:27 ` briot.emmanuel 2015-08-13 1:34 ` hreba 2015-08-13 2:53 ` Jeffrey R. Carter 2015-08-13 7:05 ` Simon Wright 2015-08-14 13:53 ` hreba 2015-08-14 16:01 ` Simon Wright 2015-08-14 17:00 ` Simon Wright 2015-08-13 7:19 ` Simon Wright 2015-08-14 13:20 ` hreba 2015-08-12 10:31 ` Markus Schöpflin 2015-08-13 1:36 ` hreba 2015-08-12 10:57 ` Simon Wright 2015-08-13 0:55 ` hreba 2015-08-13 6:58 ` Simon Wright 2015-08-18 2:16 ` hreba 2015-08-18 5:49 ` Jeffrey R. Carter 2015-08-18 7:24 ` Egil H H 2015-08-18 12:23 ` hreba 2015-08-18 12:37 ` Jacob Sparre Andersen 2015-08-18 14:02 ` hreba 2015-08-18 14:11 ` Dmitry A. Kazakov 2015-08-18 14:16 ` Jeffrey R. Carter 2015-08-18 20:56 ` Randy Brukardt 2015-08-19 1:48 ` hreba 2015-08-19 5:10 ` Jeffrey R. Carter 2015-08-19 8:44 ` Georg Bauhaus 2015-08-19 11:56 ` hreba 2015-08-19 20:53 ` Bob Duff 2015-08-18 14:15 ` Egil H H 2015-08-19 13:07 ` hreba 2015-08-18 14:16 ` Jeffrey R. Carter 2015-08-19 13:12 ` hreba 2015-08-19 20:47 ` Bob Duff 2015-08-19 21:47 ` Jeffrey R. Carter 2015-08-20 7:18 ` Dmitry A. Kazakov 2015-08-20 20:48 ` Randy Brukardt
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox