comp.lang.ada
 help / color / mirror / Atom feed
From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: C chars_ptr STORAGE_ERROR in Imported function
Date: Fri, 22 Aug 2008 14:43:15 +0300
Date: 2008-08-22T14:43:15+03:00	[thread overview]
Message-ID: <48aea5b7$0$25391$4f793bc4@news.tdc.fi> (raw)
In-Reply-To: <g8m2fv$enl$1@jacob-sparre.dk>

Kim Rostgaard Christensen wrote:
> Niklas Holsti wrote:
> 
>> Kim Rostgaard Christensen wrote:
>>
>>> Hello there
>>>
>>> I am in progress of binding the pcap c library to ada, it is a part of a
>>> school project. And for that i need a funtion that modifies a 
>>> parameter to a function like so:
>>>
>>> char    *pcap_lookupdev(char *);
>>>
  ...
> 
> the following gives me
> *** glibc detected *** double free or corruption (out): 0x0804d830 ***
> 
> raised PROGRAM_ERROR : unhandled signal
> 
>    procedure Lookup_Device is
>       function pcap_lookupdev(ebuff : Interfaces.C.Strings.Chars_Ptr) 
> return Interfaces.C.Strings.Chars_Ptr;
>       pragma Import (C, pcap_lookupdev, "pcap_lookupdev");
> 
>       Device : Interfaces.C.Strings.Chars_Ptr;
>       Errbuf_ptr  : Interfaces.C.Strings.Chars_Ptr;
>       Errbuf : Char_Array(1 .. 256);  -- the defined buffer size
>    begin

The problem is here:

>       Errbuf_Ptr := New_Char_Array(Errbuf);

New_Char_Array allocates a new char_array object, containing only 
the NUL-terminated string that is in Errbuf at this time. Since you 
have left Errbuf uninitialized, this may be a lot less than 256 
characters, so the errors are probably due to buffer overflow 
somewhere in the pcap library where it tries to put an error 
message into the char_array that Errrbuf_Ptr points to, but this 
char_array is too small.

If you want to continue with New_Char_Array, you should initialize 
Errbuf to contain a 256-character string:

    Errbuf : Char_Array (1 .. 256) := (
      others => Interfaces.C.To_C (' '));

or perhaps neater, but more complex, a NUL-terminated 255-character 
string:

    Errbuf : Char_Array (1 .. 256) := (
       1 .. 255 => Interfaces.C.To_C (' '),
       256      => Interfaces.C.nul);

Then New_Char_Array(Errbuf) will create a 256-character char_array 
that has room for the error message. (It works for me.)

If you use New_Char_Array you should also deallocate the new 
char_array by calling Interfaces.C.Strings.Free (Errbuf_Ptr) at a 
suitable point, when you no longer need this char_array.

I think it would be better to use the To_Chars_Ptr function, which 
makes a chars_ptr that points to Errbuf itself, without allocating 
another char_array, so there is no need to Free anything. This also 
needs a change in the declaration of Errbuf:

    Errbuf : aliased Char_Array := (1 .. 256 => Interfaces.C.nul);

The initial values (here nul) are irrelevant, as long as there are 
256 of them.

Then you replace the call of New_Char_Array with To_Chars_Ptr:

    Errbuf_Ptr := To_Chars_Ptr (Errbuf'Unchecked_Access, False);

followed by:

>       Device := pcap_lookupdev(Errbuf_ptr);

Also note that this can result in Device being a null pointer, 
which will cause an error in the following:

>       Ada.Text_IO.Put_Line(Value(Device));

so better check, like this:

    if Device = Null_Ptr then

       Put_Line ("Null device: " & Value (Errbuf_Ptr));

    else

       Put_Line ("Found device: " & Value (Device));

    end if;

HTH

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



  reply	other threads:[~2008-08-22 11:43 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-22  8:36 C chars_ptr STORAGE_ERROR in Imported function Kim Rostgaard Christensen
2008-08-22  9:03 ` Niklas Holsti
2008-08-22  9:55   ` Kim Rostgaard Christensen
2008-08-22 11:43     ` Niklas Holsti [this message]
2008-08-22 22:54       ` Kim Rostgaard Christensen
2008-08-22 18:48 ` anon
2008-08-22 21:55   ` tmoran
2008-08-23 10:11   ` Niklas Holsti
replies disabled

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