2016-07-11 3 views
1

Wenn GDB debuggen sagt mir folgende Fehlermeldung:C - Speicher kann nicht an der Adresse zugreifen

0x800c99ed00000001 < error: Cannot access memory at address 0x800c99ed00000001> 

Der Fehler wird erzeugt, wenn ich einen Haltepunkt setzen, wenn ich ConvertByteArrayToFloat rufen beim Debuggen.

Aber das Programm beendet ohne ein Problem und gibt mir ein Ok-Ergebnis?

Meine Hauptdatei:

#include "Local.h" 

int main(void) { 

    if(HandleReceivedMessages() == OP_COMPLETED){ 
     printf("Main Completed \n"); 
    } else { 
     printf("Main Failed \n"); 
    } 
    return 0; 
} 

Local.h

#ifndef LOCAL_H_ 
#define LOCAL_H_ 

#include "Common.h" 

T_OP_STATUS HandleReceivedMessages(void); 

#endif 

Local.c

#include "Handler.h" 
#include "Local.h" 

uint8_t message[] = {0x86, 0x9a, 0xa0, 0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x10, 0x4a, 0x00, 0x00, 0x00, 0x00, 0xe1}; 

uint8_t length = 16; 

T_OP_STATUS HandleReceivedMessages(void) { 

    if(HandleResponseMessage(message, length) == STATUS_SUCCESS) { 
     printf("Completed from Local \n"); 
     return OP_COMPLETED; 
    } else { 
     printf("Failed from Local \n"); 
     return OP_FAILED; 
    } 

} 

handler.h

#ifndef HANDLER_H_ 
#define HANDLER_H_ 

#include "Common.h" 

T_MESSAGE_STATUS HandleResponseMessage(uint8_t *requestData, uint8_t msgLength); 


#endif /* HANDLER_H_ */ 

Handler.c

#include "Handler.h" 
#include <string.h> 

static uint8_t rawRequestData[BUFFER_WIRED_SIZE]; 

static float TempFloat = 0; 


T_MESSAGE_STATUS HandleCmd(uint16_t cmdNumber, uint8_t rawDataLength, 
        uint8_t *rawDataPtr) { 

    switch (cmdNumber) { 
     case 1: 
      TempFloat = ConvertByteArrayToFloat(&rawDataPtr[3]); 
      printf("The value of the float is : %f \n", TempFloat); 
      return STATUS_SUCCESS; 
     default: 
      break; 
    } 

    return STATUS_NOT_IMPLEMENTED; 
} 


T_MESSAGE_STATUS HandleResponseMessage(uint8_t *message, 
           uint8_t msgLength) { 

    uint8_t cmdNumber, dataLength, startOfData; 


    // Check the delimiter. 
    if (message[0] & INDICATOR_UNIQUE_ADDRESS) { 

     cmdNumber = message[6]; 
     dataLength = message[7]; 
     startOfData = 8; 

    } else { 

     cmdNumber = message[2]; 
     dataLength = message[3]; 
     startOfData = 4; 
    } 

    // we copy only the real data from the command response 
    memcpy(&rawRequestData, message + startOfData, dataLength); 

    return HandleCmd(cmdNumber, dataLength, rawRequestData); 

} 

COMMON.H

#ifndef COMMON_H_ 
#define COMMON_H_ 

#include <stdint.h> 
#include <stdio.h> 

#define BUFFER_WIRED_SIZE    128 
#define INDICATOR_UNIQUE_ADDRESS  0x80 


typedef enum { 

    OP_FAILED, 
    OP_COMPLETED, 

}T_OP_STATUS; 

typedef enum 
{ 
    STATUS_SUCCESS, 
    STATUS_NOT_IMPLEMENTED, 

} T_MESSAGE_STATUS; 

float ConvertByteArrayToFloat(uint8_t *data); 


#endif /* COMMON_H_ */ 

common.c

#include "Common.h" 

float ConvertByteArrayToFloat(uint8_t *data) { 

    union { 
     uint8_t tmpArray[4]; 
     float tmpFloat; 
    } value; 

    value.tmpArray[0] = data[3]; 
    value.tmpArray[1] = data[2]; 
    value.tmpArray[2] = data[1]; 
    value.tmpArray[3] = data[0]; 

    return value.tmpFloat; 
} 

Dies ist die min-Version (es macht eine Menge Dinge wie das Format der Überprüfung Nachricht, CRC, etc ..) aber geht von Anfang bis Ende durch all diese Dateien.

Ich arbeite an einer Embedded-Plattform und beim Debuggen in meinem Mikrocontroller und Aufruf der Funktion ConvertByteArrayToFloat springt mein Programm zu einem anderen Teil meines Codes und dann stürzt es den Mikrocontroller ab.

Ich versuche, den Fehler in meinem Computer ohne den Mikrocontroller neu zu erstellen, und ich fand den Fehler an der Spitze.

+0

Was ist Ihr Mikrocontroller? Ist es Big-Endian oder Little-Endian? Sie benötigen/haben eine Funktion, die das Gegenteil von "ConvertByteArrayToFloat" (z. B. "ConvertFloatToByteArray") ist, das nicht gezeigt wird, um die Nachrichten zu erzeugen, die "ConvertByteArrayToFloat" decodiert. Sie können für die falsche Endianness hardwiring sein und die Konvertierungsfunktion explodiert, wenn der Float zurückgegeben wird. Das heißt, fest verdrahtet für [say] x86, also funktioniert es dort, aber Controller kann big-endian sein [oder umgekehrt] –

+0

Das Mikro ist Little Endian, aber die Sache ist, dass es in meinem Mikro nicht den Breakpoint im Inneren trifft ConvertByteArrayToFloat, wenn es diese Anweisung erreicht, springt es zu einem anderen nicht verwandten Teil des Codes und dann stürzt es einfach ab und geht in HardFault. Ja, es gibt auch eine ConvertFloatToByteArray, aber es wird nicht für den Moment verwendet, da ich gerade versuche, Werte zu lesen und nicht zu schreiben. – IzonFreak

+0

Sounds wie UB verursacht durch frühere UB. Ich sah die '+ 3', die sich entspannen ließ [aber dachte, du hättest das bereits überprüft]. Könnte es einen anderen Ort geben, der früher einen Puffer überläuft (d. H. Etwas Schreibtisch überprüfen), der dieses spätere Problem verursacht? Stapelüberlauf durch unbeabsichtigte Rekursion? Auf dem uC, könnte Interrupt Vektoren [welche bkpt braucht] korrumpiert werden? Versuchen Sie einen Aufruf der Konvertierungsfunktion während der frühen Initialisierung, um zu beweisen, dass es mindestens einmal funktioniert. Dann pfeffert man ihn künstlich an (dh mach es zum Kanarienvogel in der Kohlemine). Können Sie den Code (vs. bkpt) _step_? –

Antwort

2

Dies:

TempFloat = ConvertByteArrayToFloat(&rawDataPtr[3]); 

(wo rawDataPtr ist ein uint8_t * Argument) sieht sehr verdächtig. Sie übergeben einen Zeiger auf das vierte Byte bei rawDataPtr (gleich rawDataPtr + 3) an die Konvertierungsfunktion, die dann vier Bytes liest, die an dieser Stelle beginnen.

Dies sieht aus wie eine Art von Verwirrung nach dem Verzehr der ersten Bytes der Nachricht.

+0

Das rawDataPtr ist die Daten senden in der Nachricht, von diesem Ort (3) Ich weiß, dass es ein 4 Byte float in meinem Datenarray (RawDataPrt), das ist mein Wert in diesem speziellen Fall, den ich extrahieren möchte. Wenn Sie in HandleResponseMessage sehen, kopieren Sie einfach einen bestimmten Teil der Nachricht mit memcpy, das sind meine Daten, die ich dann an HandleCmd füttere. – IzonFreak

+0

@IzonFreak Nein, das sehe ich nicht. Ich sehe, wie Sie 'memcpy()' von Byte 4 in der Quelle in die 'rawData', aber dann überspringen Sie * eine andere * vier in der Zeile, die ich zitiert habe, zumindest das ist mein Verständnis gerade jetzt. – unwind

+0

@IzonFreak Ich fürchte, ich muss mich damit abfinden. Also, vom absoluten _raw_ Buffer Start, ist der Float bei Offset 4 oder 8? Das heißt, welche Header-Größe muss übersprungen werden? Wenn der Header 4 ist, sollte der Code "& rawDataPtr [0]" sein. Wenn es "& rawDataPtr [3]", _nach_ dem Vorstrich von 4/8 in 'HandleResponseMessage' sein sollte, was ist in' 0-3'? Vielleicht ist der einfache Weg, es mit Index 0 zu versuchen und zu sehen, ob UB weggeht. Oder, arbeite rückwärts. Setzen Sie das bkpt auf 'HandleCmd' oder' HandleReponseMessage' –

Verwandte Themen