2011-07-07 21 views
1

我有這個小的函數,導致我在RHEL6上頭痛,並且我不知道發生了什麼......並且這是一個調試的痛苦。當我運行這個時,我得到一個STORAGE_ERROR,所以我做了一個gstack來查看程序掛在哪裏(見下文)。它看起來像memcmp的問題,雖然我不知道它在哪裏/如何被稱爲..任何想法的解決方法?Ada問題與STORAGE_ERROR

當我改變這個函數返回'真'它似乎工作正常(STORAGE_ERROR消失),所以我認爲問題是在這部分的一些邏輯:(Ada.Characters.Handling.To_Upper( EPS_List(1).all)=「LOCALHOST」);

function Localhost_Only return Boolean is 
    --++ 
    EPS_List : String_List_Type 
       := Values(Bstring.To_Bounded_String("EPS")); 
    begin 
    return (Ada.Characters.Handling.To_Upper(EPS_List(1).all) = "LOCALHOST"); 

    end Localhost_Only; 

BEGIN編輯***

另一種方式是workst做這個(移動它的功能範圍......爲什麼這項工作?):

EPS_List : String_List_Type 
       := Values(Bstring.To_Bounded_String("EPS")); 

    function Localhost_Only return Boolean is 
    --++ 

    begin 
    return (Ada.Characters.Handling.To_Upper(EPS_List(1).all) = "LOCALHOST"); 

    end Localhost_Only; 

END編輯***

gstack輸出的過程:

Thread 1 (Thread 0x407059a0 (LWP 13610)): 
#0 0x40000424 in __kernel_vsyscall() 
#1 0x00b2b2fc in [email protected]@GLIBC_2.3.2() from /lib/libpthread.so.0 
#2 0x0b53dd9e in system__tasking__stages__vulnerable_complete_master() 
#3 0x0b53e242 in system__tasking__stages__finalize_global_tasks() 
#4 0x0b5845d3 in __gnat_last_chance_handler() 
#5 0x0b545c50 in ada__exceptions__exception_traces__unhandled_exception_terminateXn() 
#6 0x0b5459de in ada__exceptions__exception_propagation__propagate_exceptionXn() 
#7 0x0b5465c5 in __gnat_raise_nodefer_with_msg() 
#8 0x0b5469ed in ada__exceptions__raise_with_location_and_msg() 
#9 0x0b5469b8 in __gnat_raise_storage_error_msg() 
#10 0x0b546f98 in __gnat_rcheck_31() 
#11 0x0b5363de in system__interrupt_management__notify_exception() 
#12 <signal handler called> 
#13 0x0bcef590 in [email protected]@GLIBC_2.0() 
#14 0x084a83c9 in common_network_configuration__localhost_only() 

相關類型/功能:

type Number_Of_Items_Type is range 0 .. 250; 

subtype Index_Type is Number_Of_Items_Type 
    range Number_Of_Items_Type'First + 1 .. Number_Of_Items_Type'Last; 

type String_List_Type is array (Index_Type range <>) 
    of String_Access.String_P_Type; 

package Bstring is new Ada.Strings.Bounded.Generic_Bounded_Length 
          (Max => Line_Length_Type'last); 

    function Values(Name : Bstring.Bounded_String) return String_List_Type is 
    --++ 
    -- ABSTRACT 
    -- Return a list of pointers to strings. The strings are all the values 
    -- associated with the specified name. All values are recursively 
    -- evaluated so that each entry in the returned list is a primitive 
    -- name (i.e. integer, ip_address, or unix_workstation). 
    -- 
    -- If a circular definition is detected, an empty list is returned. 
    -- 
    -- LOCAL DATA 
    -- Number of items in list 
    Count : Number_Of_Items_Type := 0; 

    -- List of pointers to strings containing the primitive values 
    Out_List : String_List_Type (1 .. Index_Type'Last); 

    -- The Index of the item being evaluated 
    Item  : Config_Index_Type := 0; 

    -- A safety net, to detect and prevent unlimited recursion, such as 
    -- will happen in the case of a circular definition. 
    Depth : Number_Of_Items_Type := 0; 

    procedure Find_Values (Name : in Bstring.Bounded_String) is 
    --++ 
    -- ABSTRACT 
    -- This procedure recursively calls itself until it makes it all 
    -- The way through the Config_Array without finding a match on the 
    -- specified Name. The index of the last name for which a match was 
    -- found is used to get the value associated with that Name. This 
    -- is a primitive value associated with the name and is added to the 
    -- Out_List. 
    -- 
    -- Depth is used to count the recursion depth, when it reaches a 
    -- maximum, no more recursive calls are made, preventing an endless 
    -- loop in the case of a direct or indirect circular definition. 
    begin 
     Depth := Depth + 1; 
     for Index in 1 .. Config_Count loop 
     if Name_Match(Bstring.To_String(Name),Index) 
     and Count < Number_Of_Items_Type'last 
     and Depth < Number_Of_Items_Type'last then 
      Item := Index; 
      Find_Values (Config_Array(Index).Value); 
     end if; 
     end loop; 
     if Item /= 0 then 
     if Count < Number_Of_Items_Type'last then 
      Count := Count + 1; 
      Out_List(Count) := Config_Array(Item).Val_Ptr; 
     end if; 
     Item := 0; 
     end if; 
    end Find_Values; 

    begin -- Values 
    Find_Values(Name); 
    if Depth < Number_Of_Items_Type'last then 
     return Out_List(1..Count); 
    else 
     return Null_String_List; 
    end if; 
    end Values; 

回答

2

我絕對先在這裏猜測是,EPS_List(1)不指向一個有效的內存位置。你檢查了嗎?

盡我所知,該數組最終從指向Config_Array的指針加載。因此,如果在加載發生時沒有初始化它,或者在調用Localhost_Only之前釋放這些指針引用的內存,則會出現這種性質的錯誤。

此代碼非常複雜,我只能進入Localhost_Only並檢查它。請使用調試器查看這些指針,或在return語句之前添加調試代碼以顯示其值。

此外,您的Localhost_Only例程接受一個無約束的數組,然後假定它包含元素1。如果沒有,我相信你應該得到類似Constraint_ErrorRange_Error的東西,但是如果關閉了編譯器的範圍檢查,則可能導致Storage_Error。無論哪種方式,您都應該以某種方式防範這種可能性。喜歡的東西if EPS_List'length > 0 then return False; end if; ...


您的編輯,爲什麼移動的聲明防止崩潰我最好的猜測是,這時候在初始化發生變化。它現在發生得更早。同樣,它可能會讓它回到崩潰狀態,並試圖找出調試器和/或調試打印語句究竟發生了什麼。

+0

感謝您的幫助...您能否看看我最新的Edit?將聲明移出函數作用域......任何想法爲什麼會這樣? – systemoutprintln