Forum: Compiler & IDEs malloc verständnisproblem


von husten (Gast)


Lesenswert?

Hi

ich habe ein kleines Problem mit malloc
und zwar geht es um einen IP stack auf einem cortex M3 mit coocox IDE  + 
GCC 4.8

Dieser legt für tcp und udp verbindungen in ein struct die werte ab( 
port time usw ... )
nun soll das ganze dynamisch mit malloc erfolgen da ja nicht immer die 
verbindungen offen sind.

vorher war es so aufgebaut:
1
udp_stuct udp_table[10];  // max 10 udp verbindungen
2
3
void foo(void){ 
4
     udp_table[i].port = ... 
5
     udp_table[i].time = ... 
6
}

ich hatte mir gedacht das mal ein malloc auch auf arrayelemente machen 
kann.
also so:
1
udp_stuct *udp_table[10];  // max 10 udp verbindungen
2
3
void foo(void){ 
4
5
     udp_table[i] = (udp_stuct*)malloc( sizeof(udp_stuct) );
6
     if( udp_table[i] == NULL )
7
    return 0;
8
     memset( udp_table[i] ,0, sizeof(udp_stuct) );
9
10
     udp_table[i]->port = ... 
11
     udp_table[i]->time = ... 
12
}


irgendwann wird dann auch ein
1
free( udp_table[i] );
2
udp_table[i] = NULL;
gemacht

aber es scheint manchmal zu laufen ... und manchmal stürzt er genau beim 
malloc ab

liegt es an der evtl falschen denkweise von mir ? oder sollte DAS 
grundlegend erstmal laufen ?

kann es evtl auch daher kommen das ich verschachtelte malloc hab ?
es tritt oft auf wenn 2 bis 3 malloc hintereinander kommen.

zB
erst DHCP ( über udp es sind 2 pointer die hier genutzt werden )
die werden wieder freigegeben
danach folgt gleich ein NBNS register

erst payload allocieren ( 100byte )
dann udp öffnen ( 40byte )  <------ hier kracht es !!


er stoppt bei _malloc_r()
Hat jemand eine Idee?


Vielen Dank
Grüße

von Karl H. (kbuchegg)


Lesenswert?

husten schrieb:

>      udp_table[i] = (udp_stuct*)malloc( sizeof(udp_stuct) );

Die Adresse, die du von malloc bekommst, NICHT casten!
DAs kann einen unangenehmen Fehler unterdrücken.
malloc liefert einen void* und der ist in C ohne weiteren Cast an jeden 
anderen Pointer Type zusweisbar.
Wenn du casten musst, dann benutzt du keinen C COmpiler, sondern einen 
C++ Compiler. Und dann solltest du nicht malloc benutzen, sondern new.


> liegt es an der evtl falschen denkweise von mir ? oder sollte DAS
> grundlegend erstmal laufen ?

Das sollte erst mal grundlegend laufen, auch wenn es meistens recht 
sinnfrei ist, ein statisch allokiertes Array von Strukturen durch ein 
Array von Pointern zu ersetzen und dann durch die Allokierungen zu 
laufen. Im Endeffekt braucht das Array von Pointern ja auch 
Speicherplatz. D.h. hier greift die Abwägung: wie gross ist ein 
derartiges udp_stuct, wie groß ist in Relation dazu ein Pointer und 
wieviele udp_stuct sind im Schnitt erwartungsgemäss zu jedem Zeitpunkt 
allokiert.


> kann es evtl auch daher kommen das ich verschachtelte malloc hab ?
> es tritt oft auf wenn 2 bis 3 malloc hintereinander kommen.

Ich geh mal davon aus, dass du genug Speicher im System hast, dass die 
Speicherfragmentierung keinen Sreich spielen wird.

Von daher kann man eigentlich nur sagen: Das Problem liegt nicht im 
gezeigten Code.

: Bearbeitet durch User
von husten (Gast)


Lesenswert?

hi

Karl Heinz schrieb:
> Die Adresse, die du von malloc bekommst, NICHT casten!
> DAs kann einen unangenehmen Fehler unterdrücken.
> malloc liefert einen void* und der ist in C ohne weiteren Cast an jeden
> anderen Pointer Type zusweisbar.
> Wenn du casten musst, dann benutzt du keinen C COmpiler, sondern einen
> C++ Compiler. Und dann solltest du nicht malloc benutzen, sondern new.

ok ich MUSS nicht casten ...
hatte das aber mal versucht um evtl den Fehler zu finden.


Karl Heinz schrieb:
> Das sollte erst mal grundlegend laufen, auch wenn es recht sinnfrei ist,
> ein statisch allokiertes Array von Strukturen durch ein Array von
> Pointern zu ersetzen und dann durch die Allokierungen zu laufen. Im
> Endeffekt braucht das Array von Pointern ja auch Speicherplatz.

Ja aber das ist 1 word  .. eine struct hat 40bytes
bei tcp sind das 60 bytes insgesammt sind das 1k RAM die ich spare
Zeitlich ist das alles kein thema ...
das zieht sich nun noch durch andere quellen das ich insgesammt 4k 
weniger RAM brauch


Karl Heinz schrieb:
> Ich geh mal davon aus, dass du genug Speicher im System hast, dass die
> Speicherfragmentierung keinen Sreich spielen wird.
>
> Von daher kann man eigentlich nur sagen: Das Problem liegt nicht im
> gezeigten Code.

ich habe 32k Ram ... heap sagt nach einer weile( wnn es mal läuft.. ) 
22k free
habe dazu in der _sbrk funktion eine Variable eingefügt


nagut ... das war grundlegend erstmal die frage ob es so gehen kann ...
Ich kanne s bisher auch ganz gut  reproduzieren ...
lasse ich die nbns funktion weg funktioniert alles inkl dem webserver
es scheint sich also dort der fehler zu verbergen bzw die reihenfolge 
...


vielen Dank für die Antwort

von husten (Gast)


Lesenswert?

nachtrag...

wenn ich in der NBNS funktion  nun statt
1
char* payload;  
2
payload = malloc( xyz );
ein
1
char paylaod[ xyz ]
nutze
funktioniert das ganze ohne probleme

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

husten schrieb:
> funktioniert das ganze ohne probleme

Du hast den Fehler also erfolgreich kaschiert, statt ihn zu finden.
Glückwunsch!

von Markus (Gast)


Lesenswert?

Hi,

die Speicherverwaltung der C-Runtime merkt sich eine Liste freier 
Speicherbereiche, möglicherweise über Pointer und Größenangabe am Anfang 
eines freien Blocks.

Hast Du einen Bug in Deinem Code, der über den von malloc() 
angeforderten Speicherbereich hinausschreibt, überschreibst Du 
möglicherweise einen solchen Pointer und die Größenangabe. Der nächste 
malloc()-Aufruf greift dann ins Klo, da er die freien Blöcke nach einer 
geeigneten Größe durchsucht und dabei auf den Straypointer und die 
Murksgröße stößt.

Grüße, Markus

von Markus (Gast)


Lesenswert?

Hi,

husten schrieb:
> char* payload;
> payload = malloc( xyz );

sicher, daß xyz gereicht hat? Oder hätte es eher xyz+1 heißen müssen?
Das wäre in solcher Bug. Die Umwandlung in einen statischen Array 
verhindert das Hintenrausschreiben in einen freien Speicherbereich.

Grüße, Markus

von fbi (Gast)


Lesenswert?

Markus schrieb:
> Die Umwandlung in einen statischen Array
> verhindert das Hintenrausschreiben in einen freien Speicherbereich.

Nö, tut es nicht. Und der überschriebene Speicher ist auch nicht 
notwendigerweise frei (bei malloc aber auch nicht).

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

husten schrieb:
> nachtrag...
>
> wenn ich in der NBNS funktion  nun statt
>
1
> char* payload;
2
> payload = malloc( xyz );
> ein
1
> char paylaod[ xyz ]
> nutze
> funktioniert das ganze ohne probleme

Arrays sind keine Zeiger.

Wenn du also z.B. die Adresse von payload nimmst dann macht es einen 
großen Unterschied, ob es sich um ein Array oder einen Zeiger handelt!

von Markus (Gast)


Lesenswert?

Hi,

fbi schrieb:
> Nö, tut es nicht. Und der überschriebene Speicher ist auch nicht
> notwendigerweise frei (bei malloc aber auch nicht).

völlig sinnfreier Kommentar.
Oben drüber steht "möglicherweise".

Gruß, Markus

von Kaj (Gast)


Lesenswert?

husten schrieb:
> aber es scheint manchmal zu laufen ... und manchmal stürzt er genau beim
> malloc ab
Hast du eine Datei mit dem Start Up Code?
Ich hatte mal einen Fehler, wo das ganze beim Anlegen eines Arrays 
abgeschmiert ist... hat ne weile gedauert bis ich rausgefunden habe, 
dass der Stack/Heap in dem Start Up Code von Atmel für meinen Controller 
standardmäßig auf 1k eingestellt ist.

husten schrieb:
> ich habe 32k Ram
Und meiner hat 96k... ist aber egal wenn die Stack-/Heapgröße nicht zu 
deinen Anforderungen passt.

husten schrieb:
> und manchmal stürzt er genau beim
> malloc ab
Was genau meinst du mit abstürzen? Und wie stellst du das fest?
Wenn der Controller deiner Meinung nach "nichts" mehr macht, kann es 
sein das er im Dummy-Handler ( while(1); ) für nicht behandelte 
Interrupts hängt. Das kann passieren (so wie bei mir z.B.) wenn du was 
auf dem Stack/Heap anlegen willst, was da aber nicht mehr rauf passt.

Just my 2 cent...

von fbi (Gast)


Lesenswert?

Markus schrieb:
> völlig sinnfreier Kommentar.

Ändert aber nichts an der Tatsache das Dein Kommentar,
Zitat:
"Die Umwandlung in einen statischen Array
verhindert das Hintenrausschreiben in einen freien Speicherbereich."
genauso schwachsinnig und dazu auch noch falsch ist.

von Rolf M. (rmagnus)


Lesenswert?

husten schrieb:
> Im Endeffekt braucht das Array von Pointern ja auch Speicherplatz.
>
> Ja aber das ist 1 word  .. eine struct hat 40bytes
> bei tcp sind das 60 bytes insgesammt sind das 1k RAM die ich spare
> Zeitlich ist das alles kein thema ...

Dafür fibst du halt die Sicherheit über die Anzhal der Verbindungen auf. 
Ein statisches Array mit 10 Einträgen kann garantiert immer 10 
Verbindungen aufnehmen. Bei dynamischer Allokation machst du zwar 
Speicher frei. Wenn du den aber tatsächlich dann für was anderes nutzt, 
bedeutet das, daß die Anzahl möglicher Verbindungen sich dadurch 
reduziert. Sie kann natürlich auch höher sein, wenn wo anders gerade der 
Speicher nicht gebraucht wird, aber die Zahl hängt dann von der 
aktuellen Situation ab.
Und es ergibt sich auch ein gewisses Risiko: Wenn du viele Verbindungen 
offen hast und nun den Speicher für was anderes bräuchtest, ist dieser 
nicht mehr frei.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> Wenn du den aber tatsächlich dann für was anderes nutzt, bedeutet das,
> daß die Anzahl möglicher Verbindungen sich dadurch reduziert.

Meistens erhöht sie sich aber (im statistischen Mittel), denn die
statische Allozierung musst du „sicherheitshalber“ so groß ansetzen
wie die maximal „unter normalen Umständen“ zu erwartende Anzahl.

Dass man, wenn man ein dynamisches Problem hat (Gesamtspeicherbedarf
ist nicht vorab exakt ermittelbar) mit der Situation umgehen können
muss, dass die Ressourcen irgendwann zu Ende sind, ist bei statischer
Allozierung genauso gesetzt wie bei dynamischer, in dieser Hinsicht
hilft das also auch nicht.

von husten (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Du hast den Fehler also erfolgreich kaschiert, statt ihn zu finden.
> Glückwunsch!

das stimmt allerdings ...
grenzt für mich aber schonmal ein wo man weiter suchen kann ...

Markus schrieb:
> Hast Du einen Bug in Deinem Code, der über den von malloc()
> angeforderten Speicherbereich hinausschreibt, überschreibst Du
> möglicherweise einen solchen Pointer und die Größenangabe. Der nächste
> malloc()-Aufruf greift dann ins Klo, da er die freien Blöcke nach einer
> geeigneten Größe durchsucht und dabei auf den Straypointer und die
> Murksgröße stößt.

das KANN sein . ich werde das mal prüfen und ggf ein +1 hinzufügen

Markus schrieb:
> sicher, daß xyz gereicht hat? Oder hätte es eher xyz+1 heißen müssen?
> Das wäre in solcher Bug. Die Umwandlung in einen statischen Array
> verhindert das Hintenrausschreiben in einen freien Speicherbereich.

siehe weiter oben ..
ich werde das mal nachsehen und jedes malloc in der länge prüfen

aber auch ein array[10] kann ich grundlegend erstmal mit 20 werten 
beschreiben
spätestens nach dem pop krachts dann



Johann L. schrieb:
> Arrays sind keine Zeiger.
>
> Wenn du also z.B. die Adresse von payload nimmst dann macht es einen
> großen Unterschied, ob es sich um ein Array oder einen Zeiger handelt!

richtig ...
ich benötige jedoch für payload einen speicherbereich.
also entweder
1
char array[10];
2
//oder
3
char *buf;
4
buf = malloc ( 10 );

zB:
1
  unsigned char *payload;
2
  payload = malloc(  ARP_REQUESTLEN  );
3
  if( payload == NULL )
4
     return;
5
  memset( payload ,0, ARP_REQUESTLEN );
6
  make_arp_header( payload, 0, 0, ip , ARP_REQUEST);
7
  EMAC_SendPacket( payload, ARP_REQUESTLEN);
8
  memset( payload ,0, ARP_REQUESTLEN );
9
  free( payload );
10
  payload = NULL;
}

Kaj schrieb:
> Hast du eine Datei mit dem Start Up Code?
> Ich hatte mal einen Fehler, wo das ganze beim Anlegen eines Arrays
> abgeschmiert ist... hat ne weile gedauert bis ich rausgefunden habe,
> dass der Stack/Heap in dem Start Up Code von Atmel für meinen Controller
> standardmäßig auf 1k eingestellt ist.

habe den stack auf 2048byte gesetzt und den fix für den LPC1768 mit den 
ersten 32byte die man nicht nutzen sollte
in der_sbrk funktion wird auch nochmal geprüft ob der heap nicht dem 
stackend zu nahe kommt

Kaj schrieb:
> Was genau meinst du mit abstürzen? Und wie stellst du das fest?
> Wenn der Controller deiner Meinung nach "nichts" mehr macht, kann es
> sein das er im Dummy-Handler ( while(1); ) für nicht behandelte
> Interrupts hängt. Das kann passieren (so wie bei mir z.B.) wenn du was
> auf dem Stack/Heap anlegen willst, was da aber nicht mehr rauf passt.

er hängt sich dann auf im
1
static void Default_Handler(void) 
2
{
3
  /* Go into an infinite loop. */
4
  while (1) 
5
  {
6
            _NOP;
7
  }
8
}

Rolf Magnus schrieb:
> Dafür fibst du halt die Sicherheit über die Anzhal der Verbindungen auf.
> Ein statisches Array mit 10 Einträgen kann garantiert immer 10
> Verbindungen aufnehmen. Bei dynamischer Allokation machst du zwar
> Speicher frei. Wenn du den aber tatsächlich dann für was anderes nutzt,
> bedeutet das, daß die Anzahl möglicher Verbindungen sich dadurch
> reduziert.

ich weiß .. aber der webserver wird nur bei konfiguration benötigt ...
danach nicht mehr.
in normalen betrieb wird zyklisch man diese und jene funktion aufgerufen 
die mal speicher braucht


sicher geht das auch mit fixen arrays...
nur dachte ich ist es so etwas flexibler und brauch nicht array doppelt 
und dreifach nutzen

die funktionen werden eh nacheinander ausgeführt
somit stünde immer genug speicher bereit
das ganze läuft in einem RTOS wo später auch mal funktionen hinzukommen



ich danke nochmal für die hilfe
werde mal schauen ob ich nicht doch irgendwo "pber das ziel hinnaus 
schieße"
bzw die allocierte größe überschreibe
das ist zumindest ein guter hinweiß .. danke nochmal dafür

von Kaj (Gast)


Lesenswert?

husten schrieb:
> er hängt sich dann auf im
> static void Default_Handler(void)
> {
>   /* Go into an infinite loop. */
>   while (1)
>   {
>             _NOP;
>   }
> }
Mach den Stack doch einfach mal aus spass 4k oder 8k gross und schau ob 
er sich dann immer noch aufhaengt, du hast doch 32k. Wenn's dann immer 
noch kracht, kannst du immerhin (nahezu) sicher sein, das es nicht daran 
liegt.

Es gibt mit sicherheit ca. 1 Million Gruende warum der Controller in den 
Default_Handler springt. Ich habe aber erstmal weiter hin die 
Stack-/Heapgrenze im verdacht, einfach weil's mir auch passiert ist.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Kaj schrieb:
> Mach den Stack doch einfach mal aus spass 4k oder 8k gross

Ein typisches Setup beim GCC benutzt keinen festen Stack, sondern
gibt dem Stack das Maximum an RAM, das er bekommen kann.

von husten (Gast)


Lesenswert?

Ich danke erstmal allen für die Kommentare :-)

der Fehler lag wie immer am Programmierer :-P
ich hatte an vielen stellen schon die Größe angepasst
1
   ptr = malloc( sizeof( struct ) );

außer an 3 stellen ... dort hatte ich die #defines genutzt
problem lag daran das
1
#define XYZ 50
nicht mit dem struct übereinstimmte ...

ein
1
    malloc( sizeof( struct ) );
hilft hier ungemein

#defines sind gut .. aber gerade hierbei nicht hilfreich ...

ergebniss ist :
das #define sagte 50 bytes
sizeof sagt 68 bytes

damit zerschießt er den folgenden malloc aufruf qweil der ptr schon 
gestorben ist

Markus schrieb:
> Hast Du einen Bug in Deinem Code, der über den von malloc()
> angeforderten Speicherbereich hinausschreibt, überschreibst Du
> möglicherweise einen solchen Pointer und die Größenangabe. Der nächste
> malloc()-Aufruf greift dann ins Klo, da er die freien Blöcke nach einer
> geeigneten Größe durchsucht und dabei auf den Straypointer und die
> Murksgröße stößt.

ist des rätsels lösung

Vielen Dank für den hinweiß


grüße

von Kaj (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Kaj schrieb:
>> Mach den Stack doch einfach mal aus spass 4k oder 8k gross
>
> Ein typisches Setup beim GCC benutzt keinen festen Stack, sondern
> gibt dem Stack das Maximum an RAM, das er bekommen kann.

Mag sein, aber nicht beim verwenden von Atmel Studio.
Auszug aus den Dateien sam3x8e_flash.ld/sam3x8e_sram:.ld
1
/* The stack size used by the application. NOTE: you need to adjust according to your application. */
2
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x400;
3
4
/* The heapsize used by the application. NOTE: you need to adjust according to your application. */
5
HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : 0x200;

Bei AVRs wird das nicht gemacht, aber bei den Cortex-Controllern.

Ich weiß halt nicht wie andere IDEs/Controller-Hersteller das so 
handhaben und vorgefertigte LinkerScripte nutzen oder nicht, deswegen 
hab ich einfach darauf hingewiesen, da ich selbst vor ca. 3 Wochen 
darüber gestolpert bin.
Wenn man nicht weiß das sowas gemacht wird, kann einem das schon mal den 
ein oder anderen Tag fehlersuche bescheren :)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Was auch immer sie da verbockt haben.  Keine Ahnung, warum man eine
Stackgröße im Linkerscript festzurren will.  Es genügt doch vollauf,
die Variablen vom Anfang des RAMs nach oben zählen zu lassen und den
Stack vom Ende nach unten.

Ist ja am Ende aber die Frage, wofür dieses STACK_SIZE benutzt wird.

von husten (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Ist ja am Ende aber die Frage, wofür dieses STACK_SIZE benutzt wird.


das kann man in der SW nutzen
so habe ich die _sbrk funktion modufiziert das ein reinwachsen von heap 
in stack normalerweise geblockt wird.

das linkerscript bietet es zumindest an die stackgröße zu überwachen ...
aber innerhalb der SW wird das nirgends getan ( außer man baut dies ein 
)


man kann nun den STACK eine fixe größe geben ..
und warten bis heap irgendwann reinwächst
-> einfach weil man nur 2 variablen abfragen muss


oder man holt sich immer den aktuellen stackpointer und schaut dann nach
-> die schönere Lösung

damit stellt man auch sicher fals der erdachte STACK zu klein ist es 
trotzdem nicht kracht

von Karl H. (kbuchegg)


Lesenswert?

husten schrieb:

> damit stellt man auch sicher fals der erdachte STACK zu klein ist es
> trotzdem nicht kracht

Die Frage ist: was machst du dann?

Auf einem Desktoprechner mit Betriebssystem ist das leicht. Das laufende 
Programm wird abgewürgt, mit "letzter Kraft" wird noch eine 
Fehlermeldung ausgegeben und das Betriebssystem kriegt die Kontrolle 
zurück, die dann das Programm entsorgt.

Aber was soll auf einem kleinen µC sinnvolles geschehen?
Ich hab da nicht wirklich Freude daran, wenn die Waschmaschine mitten im 
Schleudern abschmiert, nur weil der Stack in den Heap gewachsen ist. Da 
hilft es mir dann auch nichts, wenn irgendwo verschämt eine LED auf 
diesen Fehler hinweist.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

husten schrieb:
> das kann man in der SW nutzen so habe ich die _sbrk funktion modufiziert
> das ein reinwachsen von heap in stack normalerweise geblockt wird.

Ah OK.  In der avr-libc erfolgt der entsprechende Test gegen den
aktuellen Stackpointer plus einer konfigurierbaren Sicherheitsreserve.

Karl Heinz schrieb:
> Ich hab da nicht wirklich Freude daran, wenn die Waschmaschine mitten im
> Schleudern abschmiert, nur weil der Stack in den Heap gewachsen ist.

Allerdings ist die Waschmaschine ja nun auch nicht gerade das
Musterbeispiel für eine Applikation mit stark dynamischem Datenanfall.

Bei einer solchen Applikation wiederum brauchst du immer eine
„Exit-Strategie“, wie du verfährst, wenn der Datenanfall die Kapazität
übersteigt.  Dabei ist es völlig egal, ob die statisch vorkonfigurierte
Kapazität überschritten wird oder ob malloc() keinen Speicher mehr hat.

von husten (Gast)


Lesenswert?

nunja

frage ist was der rogrammierer draus macht wenn ein

malloc( ... );

ein NULL zurück gibt!!
wenn _sbrk alarm gibt kommt aus dem malloc ein NULL ..
so ist das zumindest auf dem Cortex M


Wenn man diese sicherheit nicht abfängt schepperts eben
im Falle des IP Stacks ... er überspringt das Protokoll oder sendet mal 
nicht
fängt er sich nicht wieder .. sollte man eine sicherheit einbauen

von Eric (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Kaj schrieb:
>> Mach den Stack doch einfach mal aus spass 4k oder 8k gross
>
> Ein typisches Setup beim GCC benutzt keinen festen Stack, sondern
> gibt dem Stack das Maximum an RAM, das er bekommen kann.

Ausserdem alloziert malloc() nicht auf dem stack sondern im Heap.
Stack vergrößern bei einem malloc()-problem wird also wenig bringen...

von Eric (Gast)


Lesenswert?

Karl Heinz schrieb:
> husten schrieb:
>
>> damit stellt man auch sicher fals der erdachte STACK zu klein ist es
>> trotzdem nicht kracht
>
> Die Frage ist: was machst du dann?
>
> ... was soll auf einem kleinen µC sinnvolles geschehen?

Eintrag im Fehlerspeicher schreiben, was dann später über eine On-Board 
Diagnose (OBD) ausgelesen werden kann, und dann ein reset und hoffen 
dass alles dann gut geht.

Noch später darf dann ein armer Entwickler auf Fehlersuche, ohne dass er 
ausreichende Logs/Traces oder sonstige Infos hat. Das alles unter 
Riesendruck und direktes Management-beobachten , weil der Fehler vom 
Kunden und nicht in der hauseigenen Testabteilung gefunden wurde.

Die letztendliche Ursache liegt dann aber natürlich doch wieder beim 
Management, weil die ja einen zu kleinen uC für das Projekt ausgewählt 
hatte.
Aber darüber darf man nicht sprechen...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.