comp.lang.ada
 help / color / mirror / Atom feed
* Debugging Ada
@ 2011-12-21 15:14 awdorrin
  2011-12-21 16:45 ` Ludovic Brenta
  2011-12-22 10:28 ` Gautier write-only
  0 siblings, 2 replies; 12+ messages in thread
From: awdorrin @ 2011-12-21 15:14 UTC (permalink / raw)


I am having an odd problem with a multi-threaded application that is a
combination of C and Ada.

During elaboration, the Ada code is setting a constant string that it
retrieves from another package:

LAN_CFG_FILE : constant String := SysConfig.Cfg_Filename( LAN_CFG );

Then in the package's main procedure when I try to use the
LAN_CFG_FILE, sometimes the value is corrupted. I realize that
something is either blowing a buffer, or there is a threading issue
that is corrupting the stack, however here is my problem:

When I try to get the address of LAN_CFG_FILE in GDB, so I can set a
watch, I get the response:

"Attempt to take address of value not located in memory."

For example:
(gdb) p LAN_CFG_FILE
$7 = "/home/aldorr/config/lan.cfg"
(gdb) p LAN_CFG_FILE'Address
Attempt to take address of value not located in memory.
(gdb) p &LAN_CFG_FILE
Attempt to take address of value not located in memory.

I really am not sure why the print of the variable works, but I can't
determine where the variable is located...

This may not be an Ada issue, but more a GDB issue - but figured any
GDB forums would likely not have the Ada expertise that this forum
would.

-Al





^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 15:14 Debugging Ada awdorrin
@ 2011-12-21 16:45 ` Ludovic Brenta
  2011-12-21 16:51   ` awdorrin
  2011-12-22 10:28 ` Gautier write-only
  1 sibling, 1 reply; 12+ messages in thread
From: Ludovic Brenta @ 2011-12-21 16:45 UTC (permalink / raw)


awdorrin wrote on comp.lang.ada:
> During elaboration, the Ada code is setting a constant string that it
> retrieves from another package:
>
> LAN_CFG_FILE : constant String := SysConfig.Cfg_Filename( LAN_CFG );
[...]
> When I try to get the address of LAN_CFG_FILE in GDB, so I can set a
> watch, I get the response:
>
> "Attempt to take address of value not located in memory."

It looks like the value of LAN_CFG_FILE is preelaborated, i.e.
determined at compile time and hardcoded into the object file. In this
case, something must be overwriting it later but still at link time,
before your program runs.

--
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 16:45 ` Ludovic Brenta
@ 2011-12-21 16:51   ` awdorrin
  2011-12-21 17:18     ` Ludovic Brenta
  0 siblings, 1 reply; 12+ messages in thread
From: awdorrin @ 2011-12-21 16:51 UTC (permalink / raw)


That is what I believe is happening as well.

Is there some way I can force the compiler to not do this, but execute
the code at elaboration time instead?

I've been looking at the GNAT docs and haven't stumbled across
anything yet...



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 16:51   ` awdorrin
@ 2011-12-21 17:18     ` Ludovic Brenta
  2011-12-21 17:36       ` awdorrin
  0 siblings, 1 reply; 12+ messages in thread
From: Ludovic Brenta @ 2011-12-21 17:18 UTC (permalink / raw)


awdorrin wrote on comp.lang.ada:
> That is what I believe is happening as well.
>
> Is there some way I can force the compiler to not do this, but execute
> the code at elaboration time instead?
>
> I've been looking at the GNAT docs and haven't stumbled across
> anything yet...

Make sure that in the statement

LAN_CFG_FILE : constant String := SysConfig.Cfg_Filename( LAN_CFG );

the value of LAN_CFG is not itself preelaborated. For example, make it
the result of calling Ada.Command_Line.Argument (1) or
GNAT.OS_Lib.Getenv.

--
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 17:18     ` Ludovic Brenta
@ 2011-12-21 17:36       ` awdorrin
  2011-12-21 18:06         ` Simon Wright
  2011-12-21 19:46         ` Ludovic Brenta
  0 siblings, 2 replies; 12+ messages in thread
From: awdorrin @ 2011-12-21 17:36 UTC (permalink / raw)


Ah, I see what you are saying. I don't think that is what is going on
in this situation.

The code I'm working with is a mix of Ada and C, and it was originally
written under Ada83.

The 'SysConfig' package is importing a C character array:
  char g_cfg_file_names[100][128]; (up to 100 file names, 128
characters each)
as:
  pragma Import( C, CFG_FILES, "g_cfg_file_names");


LAN_CFG is part of an enumeration defined in the SysConfig package to
map to the index numbers of that array.

SysConfig's Cfg_Filename function is:

function Cfg_Filename( Cfg_File_Id : Cfg_File_Id_Type ) return String
is
begin
  return Interfaces.C.To_Ada( CFG_FILES(Cfg_File_Id), Trim_Nul =>
True);
end Cfg_Filename;

So back in the LAN package:

procedure LAN is

  LAN_CFG_FILE : constant String := SysConfig.Cfg_Filename( LAN_CFG );

  ...

begin

  Process_Config_File( LAN_CFG_FILE );

end;

I've placed breaks on the line where LAN_CFG_FILE is set and then
where it is used.

When it is set, I can print the value that is assigned, but I cannot
print the address of the variable/constant LAN_CFG_FILE - which makes
me think that the Ada compiler is just putting the string in the code
where it is used at the Process_Config_File call, rather than storing
it in the LAN_CFG_FILE variable.

I can find a location in memory where the filename is stored - but
there does not appear to be a 'LAN_CFG_FILE' variable anywhere...




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 17:36       ` awdorrin
@ 2011-12-21 18:06         ` Simon Wright
  2011-12-21 18:43           ` awdorrin
  2011-12-21 19:46         ` Ludovic Brenta
  1 sibling, 1 reply; 12+ messages in thread
From: Simon Wright @ 2011-12-21 18:06 UTC (permalink / raw)


awdorrin <awdorrin@gmail.com> writes:

> I can find a location in memory where the filename is stored - but
> there does not appear to be a 'LAN_CFG_FILE' variable anywhere...

Perhaps if you (temporarily) removed the 'constant'?



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 18:06         ` Simon Wright
@ 2011-12-21 18:43           ` awdorrin
  0 siblings, 0 replies; 12+ messages in thread
From: awdorrin @ 2011-12-21 18:43 UTC (permalink / raw)


On Dec 21, 1:06 pm, Simon Wright <si...@pushface.org> wrote:
> awdorrin <awdor...@gmail.com> writes:
> > I can find a location in memory where the filename is stored - but
> > there does not appear to be a 'LAN_CFG_FILE' variable anywhere...
>
> Perhaps if you (temporarily) removed the 'constant'?

GDB appears to be confused when trying to display these variables,
whether the 'constant' tag is there or not.

What we just tried was appending a null to the string:

LAN_CFG_FILE : constant String := SysConfig.Cfg_Filename( LAN_CFG ) &
Ascii.Nul;

When we do this, with or without the 'constant' tag, the
'lan_cfg_file' becomes a variable that can be referenced.

'p lan_cfg_file' gives: $3 =   ""
'p &lan_cfg_file' gives: $4 = (access array (...) of character)
0xf2aced90

dumping the memory at that location:
'x /2s 0xf2aced90' gives:

 0xf2aced90: "/home/aldorr/prog/data/config/lan1.cfg["00"]"
 0xf2acedb7: "["f7}{"d0"]["la"]["ba"]["f7"]["00"]"

(assuming the second line is just garbage in uninitialized memory)

I'm not entirely sure why GDB is seeing this as an 'access array of
characters' rather than an Ada String, but I'm guessing that is an
artifact of GDB.





^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 17:36       ` awdorrin
  2011-12-21 18:06         ` Simon Wright
@ 2011-12-21 19:46         ` Ludovic Brenta
  2011-12-22  7:21           ` Adam Beneschan
  1 sibling, 1 reply; 12+ messages in thread
From: Ludovic Brenta @ 2011-12-21 19:46 UTC (permalink / raw)


awdorrin <awdorrin@gmail.com> writes:
> Ah, I see what you are saying. I don't think that is what is going on
> in this situation.
>
> The code I'm working with is a mix of Ada and C, and it was originally
> written under Ada83.
>
> The 'SysConfig' package is importing a C character array:
>   char g_cfg_file_names[100][128]; (up to 100 file names, 128
> characters each)
> as:
>   pragma Import( C, CFG_FILES, "g_cfg_file_names");
>
> LAN_CFG is part of an enumeration defined in the SysConfig package to
> map to the index numbers of that array.

OK, I think I understand the problem better too.  Your initial
description of the problem was:

> Then in the package's main procedure when I try to use the
> LAN_CFG_FILE, sometimes the value is corrupted.

I'm beginning to think that perhaps the elaboration order varies between
compilations.  The pragma Import (C, CFG_FILES, "g_cfg_file_names")
indicates that:

- the Ada language rules require that g_cfg_file_names is elaborated
  before LAN_CFG_FILE
- the Ada compiler cannot enforce this rule, so it simply assumes that
  the rule is followed
- the C compiler must emit code that elaborates *and* initializes
  g_cfg_file_names.  It is possible that what you see as "corrupted" is
  simply an uninitialized value.
- the binder must emit code that calls the C initialization routine
  *before* the elaboration of LAN_CFG_FILE

Maybe you should inspect the binder-generated file (b~*.adb) to see what
happens.  It is this file that does the elaboration, so it is fairly
easy to see what gets elaborated first.  Also, you can place a
breakpoint in this file, just like in any other file, before running
your program in gdb.  This might help too.

HTH

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 19:46         ` Ludovic Brenta
@ 2011-12-22  7:21           ` Adam Beneschan
  2011-12-22  8:39             ` Ludovic Brenta
  2011-12-22 12:20             ` awdorrin
  0 siblings, 2 replies; 12+ messages in thread
From: Adam Beneschan @ 2011-12-22  7:21 UTC (permalink / raw)


On Dec 21, 11:46 am, Ludovic Brenta <ludo...@ludovic-brenta.org>
wrote:
> awdorrin <awdor...@gmail.com> writes:
> > Ah, I see what you are saying. I don't think that is what is going on
> > in this situation.
>
> > The code I'm working with is a mix of Ada and C, and it was originally
> > written under Ada83.
>
> > The 'SysConfig' package is importing a C character array:
> >   char g_cfg_file_names[100][128]; (up to 100 file names, 128
> > characters each)
> > as:
> >   pragma Import( C, CFG_FILES, "g_cfg_file_names");
>
> > LAN_CFG is part of an enumeration defined in the SysConfig package to
> > map to the index numbers of that array.
>
> OK, I think I understand the problem better too.  Your initial
> description of the problem was:
>
> > Then in the package's main procedure when I try to use the
> > LAN_CFG_FILE, sometimes the value is corrupted.
>
> I'm beginning to think that perhaps the elaboration order varies between
> compilations.  The pragma Import (C, CFG_FILES, "g_cfg_file_names")
> indicates that:
>
> - the Ada language rules require that g_cfg_file_names is elaborated
>   before LAN_CFG_FILE
> - the Ada compiler cannot enforce this rule, so it simply assumes that
>   the rule is followed
> - the C compiler must emit code that elaborates *and* initializes
>   g_cfg_file_names.  It is possible that what you see as "corrupted" is
>   simply an uninitialized value.
> - the binder must emit code that calls the C initialization routine
>   *before* the elaboration of LAN_CFG_FILE

If LAN_CFG_FILE is declared inside a procedure as shown in a previous
post, how can elaboration order be an issue?

                               -- Adam



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-22  7:21           ` Adam Beneschan
@ 2011-12-22  8:39             ` Ludovic Brenta
  2011-12-22 12:20             ` awdorrin
  1 sibling, 0 replies; 12+ messages in thread
From: Ludovic Brenta @ 2011-12-22  8:39 UTC (permalink / raw)


Adam Beneschan wrote on comp.lang.ada:
> If LAN_CFG_FILE is declared inside a procedure as shown in a previous
> post, how can elaboration order be an issue?

It was my understanding from the very beginning that LAN_CFG_FILE
was a constant declared in a package, not a subprogram; it is the OP
who
suspects a problem with elaboration.

--
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-21 15:14 Debugging Ada awdorrin
  2011-12-21 16:45 ` Ludovic Brenta
@ 2011-12-22 10:28 ` Gautier write-only
  1 sibling, 0 replies; 12+ messages in thread
From: Gautier write-only @ 2011-12-22 10:28 UTC (permalink / raw)


A solution would be to use an all-Ada Config package, so you don't
need to worry with the C mess.
You find a Config package here:

  http://sf.net/projects/ini-files/

Have fun
_________________________
Gautier's Ada programming
http://gautiersblog.blogspot.com/search/label/Ada
NB: follow the above link for a valid e-mail address



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Debugging Ada
  2011-12-22  7:21           ` Adam Beneschan
  2011-12-22  8:39             ` Ludovic Brenta
@ 2011-12-22 12:20             ` awdorrin
  1 sibling, 0 replies; 12+ messages in thread
From: awdorrin @ 2011-12-22 12:20 UTC (permalink / raw)


On Dec 22, 2:21 am, Adam Beneschan <a...@irvine.com> wrote:
>
> If LAN_CFG_FILE is declared inside a procedure as shown in a previous
> post, how can elaboration order be an issue?
>
>                                -- Adam

Ugh, you are right! I was under the impression that this LAN file was
a separate package and kept reading the 'procedure LAN' line as
'package LAN'... which was making me think the problem was elaboration
related...  I think this impression was enforced by the long delay
between the declaration section being executed and the body of the
procedure being called. I'll need to take a fresh look at this when I
get into work this morning.

Now, I'm thinking that the cause is likely related to compiler
optimization, and that optimization is not occurring when we append
the Null character at the end of the string.


Regarding the suggestion to use an all Ada config package, the code
I'm working on was originally developed in the mid 80s and is a
combination of Ada and C. It has been migrated from multiple platforms
over the past 25 years, and there are limitations to what I can
change. If I had my way, we would be redesigning/reimplementing this
using modern concepts rather than on the original limitations of the
Ada83 language. :)





^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-12-22 12:20 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-21 15:14 Debugging Ada awdorrin
2011-12-21 16:45 ` Ludovic Brenta
2011-12-21 16:51   ` awdorrin
2011-12-21 17:18     ` Ludovic Brenta
2011-12-21 17:36       ` awdorrin
2011-12-21 18:06         ` Simon Wright
2011-12-21 18:43           ` awdorrin
2011-12-21 19:46         ` Ludovic Brenta
2011-12-22  7:21           ` Adam Beneschan
2011-12-22  8:39             ` Ludovic Brenta
2011-12-22 12:20             ` awdorrin
2011-12-22 10:28 ` Gautier write-only

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox