Domanda

Attualmente stiamo sviluppando un'applicazione per un MCU msp430, e sono in esecuzione in alcune strani problemi.Abbiamo scoperto che la dichiarazione di matrici entro un ambito di applicazione dopo la dichiarazione delle variabili "normali", a volte cause di quello che sembra essere un comportamento indefinito.Come questa:

foo(int a, int *b);

int main(void)
{
    int x = 2;
    int arr[5];

    foo(x, arr);

    return 0;
}

pippo è passato un puntatore come la seconda variabile, che a volte non scegliere il arr array.Possiamo verificare questo è solo l'esecuzione del programma, e vedere che il valore dell'array arr-come-un-puntatore variabile lo scopo principale non è la stessa come valore di b puntatore variabile pippo ambito.E no, questo non è davvero riproducibili, abbiamo appena osservato questo comportamento una volta in un po'.

Questo è osservabile anche prima dell'inizio dei foo funzione viene eseguita, il passato puntatore parametro (b) è semplicemente indicando l'indirizzo che arr è.

Cambiando l'esempio sembra risolvere il problema, come questo:

foo(int a, int *b);

int main(void)
{
    int arr[5];
    int x = 2;

    foo(x, arr);

    return 0;
}

Qualcuno ha qualche input o suggerimenti perché abbiamo esperienza di questo comportamento?O esperienze simili?L'MSP430 guida alla programmazione specifica che il codice deve essere conforme a ANSI C89 spec.e quindi mi chiedevo se si dice che l'array deve essere dichiarata prima non variabili array?

Qualsiasi input su questo sarebbe apprezzato.


Aggiornamento

@Adam Shiemke e tomlogic:

Mi chiedo che cosa C89 specifica sui diversi modi di inizializzazione dei valori all'interno di dichiarazioni.Siete autorizzati a scrivere qualcosa come:

int bar(void)
{
    int x = 2;
    int y;

    foo(x);
}

E se sì, che dire:

int bar(int z)
{
    int x = z;
    int y;

    foo(x);
}

È che è permesso?Presumo che devono essere illegale C89:

int bar(void)
{
    int x = baz();
    int y;

    foo(x);
}

Grazie in anticipo.


Aggiorna 2 Problema risolto.Fondamentalmente siamo dove disabilitazione degli interrupt prima di chiamare la funzione (pippo) e dopo le dichiarazioni di variabili.Siamo riusciti a riprodurre il problema per fare un esempio semplice, e la soluzione sembra essere quella di aggiungere un _NOP() istruzione dopo l'disattivare la chiamata di interrupt.

Se qualcuno è interessato mi può postare un esempio completo di riprodurre il problema, e la correzione?

Grazie per tutte le informazioni su questo.

È stato utile?

Soluzione

Si dovrebbe essere in grado di determinare se si tratta di un bug del compilatore basato sull'assemblaggio di codice che viene prodotto.È l'assemblaggio di diverse quando si cambia l'ordine delle dichiarazioni di variabile?Se il debugger consente, tenta di avanzare e retrocedere, attraverso il montaggio.

Se si trova un bug del compilatore, inoltre, verificare l'ottimizzazione.Ho visto bug come questo è stato introdotto dall'ottimizzatore.

Altri suggerimenti

Che sembra un bug del compilatore.

Se si utilizza il primo esempio (quello problematico) e scrivere la vostra chiamata di funzione come foo(x, &arr[0]);, non vedi gli stessi risultati?Che cosa succede se si inizializza l'array come int arr[5] = {0};?Nessuno di questi dovrebbe cambiare nulla, ma se lo fanno, vorrei accennare a un bug del compilatore.

Nel tuo aggiornati domanda:

Fondamentalmente siamo dove disabilitazione degli interrupt prima di chiamare la funzione (foo) e dopo le dichiarazioni di variabili.Siamo riusciti a riprodurre il problema per fare un esempio semplice, e la soluzione sembra essere quella di aggiungere un _NOP() istruzione dopo l'disattivare la chiamata di interrupt.

Sembra come se l'interrupt disattivazione intrinseca/funzione/macro (o comunque gli interrupt sono disabilitati) potrebbe essere causato da un'istruzione di essere 'saltato' o qualcosa del genere.Mi piacerebbe indagare se è codificato/funzioni correttamente.

Entrambi gli esempi sembrano essere conforme C89 per me.Non ci dovrebbero essere osservabili differenza nel comportamento supponendo che foo non accede oltre i limiti della matrice.

Per C89, le variabili devono essere dichiarate nell'elenco all'inizio del campo di applicazione prima di entrare in servizio.C99 permette di unire l'assegnazione di un dichiarazione.Così:

{ 
    int x; 
    int arr[5];

    x=5;
...

è legale c89 stile.Mi sorprende che il tuo compilatore non gettare qualche tipo di errore che se non supporta c99.

Supponendo che il codice vero e proprio è molto più complesso, heres alcune cose che vorrei controllare, tenere a mente sono supposizioni:

Potrebbe essere traboccante lo stack occasione?Se è così potrebbe essere qualche artefatto di "stack" difesa dal compilatore/uC?Il valore non corretto di &pippo rientrano all'interno di un stimabile intervallo di memoria?se è così significa che hanno un qualche significato (all'interno dello stack, ecc)?

Il mcu430 hanno diverse gamme di ram e la rom di indirizzamento?Che è, è lo spazio di indirizzo per la ram a 16 bit, mentre il programma spazio di indirizzi a 24 bit?PIC dispone di una tale architettura, per esempio.Se è così sarebbe fattibile che arr è sempre assegnato come rom (24bit) e che la funzione si aspetta un puntatore di ram (16bit) il codice funziona quando arr stati stanziati i primi 16 bit di indirizzo di spazio ma di mattoni se è sopra di questo range.

Forse avete in qualche luogo nel vostro programma in memoria illegali scrivere che corrompe il vostro stack.

Avete dato un'occhiata allo smontaggio?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top