2016-01-13 16 views
5

Sto scrivendo un programma Ada utilizzando il sottoinsieme Ravenscar (quindi, sono a conoscenza del numero di attività in esecuzione al momento dell'esecuzione). Il codice è compilato da gcc con lo switch -fstack-check abilitato. Ciò dovrebbe causare il programma aumentare un STORAGE_ERROR in fase di esecuzione se uno qualsiasi dei miei compiti supera il loro stack.Best practice per determinare l'utilizzo dello stack nel programma Ravenscar

Ada permette di impostare il limite superiore per coloro (task-specific) pile durante la specificazione del rispettivo compito in questo modo:

pragma Storage_Size (Some_Value); 

Ora mi chiedevo cosa opzioni che ho per determinare Some_Value. Quello che ho sentito fino ad ora:

  1. Fai ipotesi finché non viene più sollevato STORAGE_ERROR. Questo è più o meno ciò che l'OP suggerisce here.
  2. Inserire qui l'uscita di -fstack-usage.
  3. Utilizzare alcune estensioni specifiche di gnat come indicato here (in che cosa si differenzia tecnicamente dall'articolo 2?).
  4. Ottieni un analizzatore di stack come gnatstack e lascia che faccia il lavoro per te.

Se ho capito bene tutte le tecniche di cui sopra sono dinamico (cioè esse richiedono il programma da eseguire per lavorare). Anche gli approcci statici sono concepibili? Per esempio. limitandomi ulteriormente attraverso alcune delle opzioni ad alta integrità di Ada (come ad esempio No_Recursion, che altro?).

Forse qualcuno di voi può indicare alcune best practice per affrontare questo problema e/o estendere/commentare la mia lista (sicuramente incompleta).

Domanda bonus: Qual è la dimensione predefinita dello stack di un task quando il pragma precedente non è specificato? Lo docs di GCC indica solo che questo valore dipende dal runtime, senza fornire numeri concreti.

+1

Buona domanda con una buona ricerca di fondo! –

+0

La dimensione dello stack predefinita è data in 'System.Parameters.Default_Stack_Size' (file' s-parame.adb'). –

+0

@Simon: la dimensione dello stack è correlata all'attività dell'ambiente, alle attività dichiarate o a tutte le attività? Chiedo perché mi sono imbattuto in un'opzione "imposta lo stack size" che non ha influenzato il task di ambiente - che apparentemente non è stato settabile in alcun modo con quella specifica release del compilatore, che ha anche disobbedito alle impostazioni di ulimit. Ho lavorato attorno ad esso spostando l'intero programma in un nuovo compito ... –

risposta

1

In genere è possibile controllare lo spazio di stack richiesto dai singoli tipi con l'attributo 'Storage_Size (che conta in bit).

Una volta inserito questo tabulato (potrebbe essere necessario arrotondarlo a intere parole/doppie parole), è possibile sommare quanto spazio pila viene utilizzato da ciascuna regione dichiarativa e quindi percorrere le chiamate per trovare il massimo Impilare l'utilizzo.

+0

Stai suggerendo di farlo manualmente? Sembra uno sforzo noioso ... C'è forse qualche strumento di supporto per questo? – morido

+1

Ti stavo letteralmente suggerendo di farlo manualmente. Dubito che tu possa farlo attraverso l'analisi statica a meno che non ti limiti a non usare la ricorsione. Se non si utilizza la ricorsione, dovrebbe essere possibile scrivere un piccolo strumento basato su ASIS per eseguire il lavoro. –