Hallo, ich hab schon auf google viel Zeit verbracht, aber ich verstehe
es noch nicht ganz.
Mein Code erzeugt einen Hardfault, diesen Fehler konnte ich mit
"auskommentiern" finden.
Aber wie findet man das ganze eleganter/schneller? Ich hab einen J-Link
ohne ETM-Trace und die Keil EDU. Der Controller ist ein
STM32F103C8/M3-Core.
IBUSERR heißt, dass der M3 den Fehler beim prefetch erkannt hat?
BFARVALID ist nicht gesetzt, also BFAR ignorieren oder?
Peter Trace schrieb:> Aber wie findet man das ganze eleganter/schneller?
In dem man immer selber eine Routine für den Hard Fault definiert und
dort einen Breakpoint platziert. Den Grund für den Hard Fault kann man
dann auslesen.
step one schrieb:> In dem man immer selber eine Routine für den Hard Fault definiert und> dort einen Breakpoint platziert. Den Grund für den Hard Fault kann man> dann auslesen.
Und an SP+24 auch die Faultadresse, was einem zusammen mit dem Mapfile
verrät, wo der Fehler passiert ist.
Hilft dir bei einem Stackfehler wie oben aber nur bedingt.
Der Hardfault tritt dann meist nicht dort auf wo der Stack kaputtgemacht
wird.
Bei vielen anderen Zugriffs-Fehlern hilft es allerdings.
Wenn deine Entwicklungsumgebung kein einfaches 'Backtrace' hat, dass
auch aus einem Hardfault funktioniert, wechsle zu einer die das kann,
oder baue dir ein Workaround das auf Kommando ein Backtrace liefert.
Alles andere ist doch sehr suboptimal..
Peter Trace schrieb:> void uart_get_time(void)> {> sprintf(str,"System-Uhrzeit %0.2d:%0.2d:%0.2dUhr \n", stu, min, sek);> }>> Aber wie findet man das ganze eleganter/schneller?
Indem man snprintf() (mit der Betonung auf 'n') verwendet. Dass es
sprintf() immer noch gibt ist eine Gemeinheit.
Manche Stack-Fehler kann man mit der MPU abfangen. Aber auch ohne MPU
kann man den Stack auf der niedrigsten RAM-Adresse beginnen lassen. Dann
gibt es einen Bus Error, wenn der Stack zu voll wird. Ich werde nie
verstehen, was so toll daran ist, wenn der Stack den Heap überschreibt.
Masochismus?
> Ich hab einen J-Link ohne ETM-Trace und die Keil EDU.
Mit dem GCC und den binutils bekommst du das Kommandozeilen Tools
addr2line, das zeigt dir die Quelltextzeile passend zur Fault Adresse
bei SP+24 an. Wenn allerdings der Stack überschrieben wurde... Aber das
passiert dank snprintf() ja nicht :)
Dr. Sommer schrieb:> Hmm, wenn man C++ nutzt kann man einen kleinen Trick machen um den> sprintf-Fehler zu vermeiden:> ...> Dann wird die Array-Größe automatisch übergeben; man kann sie nicht> vergessen, und auch nicht falsch angeben. Ungetestet :)
Ja, oder man nimmt dann gleich die string-Klasse ala:
1
my_text<<"Hallo";
Aber das wäre dann wohl zu einfach für dich oder?
mfg
Felix F. schrieb:> Ja, oder man nimmt dann gleich die string-Klasse ala:
Welche string-Klasse kann das, und kommt die ohne dynamischen Speicher
aus, so wie s(n)printf?
Dr. Sommer schrieb:> Felix F. schrieb:>> Ja, oder man nimmt dann gleich die string-Klasse ala:>> Welche string-Klasse kann das, und kommt die ohne dynamischen Speicher> aus, so wie s(n)printf?
So weit mir bekannt, gibt es nur 1 std::string Klasse und die kann
natürlich alles, was auch im Standard definiert ist. Worauf willst du
hinaus?
Wenn ich keine dyn. Speicherallokierung will, dann verwendet man halt
Plain-C wie snprintf (wie bereits genannt) und keine auf irgendwelche
Spezialfälle zusammengeschusterten Mixes die deine Speicherfehler
verschleiern.
mfg
Felix F. schrieb:> So weit mir bekannt, gibt es nur 1 std::string Klasse und die kann> natürlich alles, was auch im Standard definiert ist. Worauf willst du> hinaus?
Darauf, dass sie nicht das kann, was du vorgeschlagen hast (Operator
<<).
Felix F. schrieb:> Wenn ich keine dyn. Speicherallokierung will, dann verwendet man halt> Plain-C wie snprintf (wie bereits genannt) und keine auf irgendwelche> Spezialfälle zusammengeschusterten Mixes die deine Speicherfehler> verschleiern.
Begründung? Der Speicherfehler wird verhindert, nicht verschleiert.
Peter Trace schrieb:> Hallo, ich hab schon auf google viel Zeit verbracht, aber ich verstehe> es noch nicht ganz.>> Mein Code erzeugt einen Hardfault, diesen Fehler konnte ich mit> "auskommentiern" finden.>> Aber wie findet man das ganze eleganter/schneller? Ich hab einen J-Link> ohne ETM-Trace und die Keil EDU. Der Controller ist ein> STM32F103C8/M3-Core.>> IBUSERR heißt, dass der M3 den Fehler beim prefetch erkannt hat?> BFARVALID ist nicht gesetzt, also BFAR ignorieren oder?
Du landest ja im hard fault handler mit der Endlosschleife. Dann gehst
du in callstack and locals und wählst den Händler aus und lässt dir im
Kontextmenü den caller geben. Dann wird dir die Stelle in code und
disassembly gezeigt.
Dr. Sommer schrieb:> Felix F. schrieb:>> So weit mir bekannt, gibt es nur 1 std::string Klasse und die kann>> natürlich alles, was auch im Standard definiert ist. Worauf willst du>> hinaus?>> Darauf, dass sie nicht das kann, was du vorgeschlagen hast (Operator> <<).>> Felix F. schrieb:>> Wenn ich keine dyn. Speicherallokierung will, dann verwendet man halt>> Plain-C wie snprintf (wie bereits genannt) und keine auf irgendwelche>> Spezialfälle zusammengeschusterten Mixes die deine Speicherfehler>> verschleiern.> Begründung? Der Speicherfehler wird verhindert, nicht verschleiert.
Oh, stimmt. Habe das mit stringstream verwechselt. Muss natürlich '='
lauten. Ändert aber jetzt vom Prinzip der automatischen Größenanpassung
nichts.
Wenn ich in str[10] mehr als 10 Zeichen schreiben kann, wird der Fehler
verschleiert. Wenn ich dahinter einfach reserved[10] schreibe, ist der
Fehler auch behoben, weil ich jetzt in reserved schreibe. Schöner wirds
dadurch aber auch nicht.
mfg
Felix F. schrieb:> Wenn ich in str[10] mehr als 10 Zeichen schreiben kann, wird der Fehler> verschleiert.
Kannst du nicht. Die autosprintf-Funktion übergibt automatisch "10" an
snprintf, und der String wird abgeschnitten, es wird nichts in
"reserved" geschrieben, es tritt kein Buffer Overflow ein.
P.Loetmichel schrieb:> Das macht Bascom schon immer so.
D.h. man kann da nie aus Effizienzgründen bei sauberer Programmierung
die Range-Checks abschalten? Schwach.
Dr. Sommer schrieb:> Felix F. schrieb:>> Wenn ich in str[10] mehr als 10 Zeichen schreiben kann, wird der Fehler>> verschleiert.>> Kannst du nicht. Die autosprintf-Funktion übergibt automatisch "10" an> snprintf, und der String wird abgeschnitten, es wird nichts in> "reserved" geschrieben, es tritt kein Buffer Overflow ein.
Achso, dann habe ich da was falsch verstanden.
Dann würde ich aber gleich zum korrekten Ansatz raten:
Felix F. schrieb:> Dann würde ich aber gleich zum korrekten Ansatz raten:
Wenn man jetzt aber die Array-Größe auf "MAX-3" ändert muss man dran
denken, das bei snprintf auch zu tun. Mit dem template entfällt das,
weil automatisch immer die tatsächliche Array-Größe genutzt wird.
Peter Trace schrieb:> Hallo, ich hab schon auf google viel Zeit verbracht, aber ich verstehe> es noch nicht ganz.
Tja. Das sind die Leiden der jungen Ignoranten, die partout sich auf
einem µC genau so benehmen wollen wie auf dem PC, wo sie ein
fürsorgliches Betriebssystem und schier unendlich viel RAM haben.
Aber der TO hat wohl sein Problem aus den Augen verloren, also was
soll's.
W.S.
Dr. Sommer schrieb:> Felix F. schrieb:>> Dann würde ich aber gleich zum korrekten Ansatz raten:>> Wenn man jetzt aber die Array-Größe auf "MAX-3" ändert muss man dran> denken, das bei snprintf auch zu tun. Mit dem template entfällt das,> weil automatisch immer die tatsächliche Array-Größe genutzt wird.
das kann man in C auch haben, normalerweise schreibt man ja
temp schrieb:> Dafür sieht man die Spatzen vor lauter Kanonenkugeln nicht.
Damit kein Missverständnis aufkommt, das war allgemein auf einige der
Vorschläge hier bezogen nicht auf den letzten von Bauform B. Der ist
zeitlich dazwischen gerutscht.
Vielen Dank für die zahlreichen Antworten.
Mir geht es bei dieser Frage nicht um die Vermeidung von Fehlern bei
"printf", sondern nur um die Fehlerlokalisierung.
Witziger weise wurde under "Stack-Caller" keine Funktion angezeigt, das
hat mich zum grübeln gebracht.
Peter Trace schrieb:> Witziger weise wurde under "Stack-Caller" keine Funktion angezeigt, das> hat mich zum grübeln gebracht.
Wenn du dir den Stack zerschießt ist das nun mal so.