From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,6c7dea22b75ba442 X-Google-Attributes: gid103376,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news3.google.com!out01a.usenetserver.com!news.usenetserver.com!in04.usenetserver.com!news.usenetserver.com!newsfeed.icl.net!newsfeed.fjserv.net!newsfeed.cw.net!cw.net!news-FFM2.ecrc.de!newsfeed00.sul.t-online.de!t-online.de!feeder.news-service.com!proxad.net!cleanfeed2-b.proxad.net!nnrp17-1.free.fr!not-for-mail From: Samuel Tardieu Newsgroups: comp.lang.ada Subject: Re: ada compiler? References: <1194747665.6151.31.camel@K72> <_evZi.177931$Xa3.50640@attbi_s22> <87hcjq46t4.fsf@ludovic-brenta.org> <473abc9d$0$13104$9b4e6d93@newsspool2.arcor-online.net> <1195035988.599522.87580@50g2000hsm.googlegroups.com> <1195043147.1007.263.camel@kartoffel> <1195052954.315227.220840@o3g2000hsb.googlegroups.com> <1195056238.1007.317.camel@kartoffel> <1195058211.682783.288340@d55g2000hsg.googlegroups.com> Date: Fri, 16 Nov 2007 02:07:15 +0100 Message-ID: <87pryb2e2k.fsf@willow.rfc1149.net> User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) Cancel-Lock: sha1:qt7OerPdepFmfNvaEz7uTerCQpw= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Leafnode-NNTP-Posting-Host: 2001:6f8:37a:2::2 Organization: Guest of ProXad - France NNTP-Posting-Date: 16 Nov 2007 02:10:01 MET NNTP-Posting-Host: 88.191.14.223 X-Trace: 1195175401 news-1.free.fr 26660 88.191.14.223:48211 X-Complaints-To: abuse@proxad.net Xref: g2news1.google.com comp.lang.ada:18428 Date: 2007-11-16T02:10:01+01:00 List-Id: >>>>> "Ludovic" == Ludovic Brenta writes: Ludovic> Does someone here know GNAT internals in sufficient detail as Ludovic> to enlighten us? Also can someone explain what "reliable" Ludovic> stack checking is in GNAT parlance? You have two ways of doing stack checking: 1- at the GCC level by checking the stack at the entry of every subprogram and comparing it to a thread/task specific marker; this is costly 2- at the OS level by mapping a page after the stack which does not allow either reads or writes to the page (or, when this is not possible, which doesn't allow writes) Let me describe how solution 2 is implemented, assuming the stack grows downwards: (from higher to lower addresses) | | Stack for task T1 | v | | Allowed space for stack for task T1 | - | | Protected memory page | - | | Stack for task T2 | v If stack for task T1 slowly grows downwards, it will eventually reach the protected memory page and raise a SIGSEGV to represent the access violation. However, if you allocate an object on stack T1 larger than the remaining task space + the size of a protected memory page, then you may end up with something looking like: (say a large T1Obj array is allocated on the stack) | | Stack for task T1 | | Return address for previous function call | Stack frame (I won't detail here what it is) for current funcall | Address of T1Obj[6] | Address of T1Obj[5] - | Address of T1Obj[4] | Address of T1Obj[3] Protected memory page | Address of T1Obj[2] - | Address of T1Obj[1] | Stack for task T2 | v You may then write T1Obj[1] without triggering a memory protection error and overwrite the stack of task T2 without noticing. If you modify only T1Obj[1] and return, you will leave T2 with a corrupted task. So to make this scheme work, every subprogram must use a stack area smaller than a page size (typically 4KB, but this may vary from system to system and you may also have pages of different sizes to reduce the number of MMU [memory management unit] lookups that you need to map your process virtual address space into the physical+swap address space). I have not checked if GNAT knows how to mix those two schemes, i.e. if it can generate a call to Stack_Check only in functions where the local stack area is large enough to mandate the check and in subprograms callable from other languages (because they may have had the same problem and not done the check themselves -- in case of problems, the program should be aborted as other stacks may already have been corrupted). An obvious improvement would be to increase the number of protected memory pages between different stacks. However, this would reduce the number of tasks that you can run simultaneously because on a 32 bits system you have access to a maximum 4GB of addressable memory from any processus (usually 3GB under Linux for example). Does that answer your question? Sam -- Samuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/