Zajmuję się tworzeniem niektórych modułów dla systemu automatyzacji napisanego w języku C i muszę wykonać wiele pracy ze sprzętem. I nie widzę prostego sposobu (jak tradycyjne) do debugowania rzeczy zamiast dzienników śledzenia. Tak więc szukam dobrej praktyki do rejestrowania wywołań funkcji. Co najmniej sekwencja wywołań i wartości zwracanych.Śledzenie wywołań funkcji w C
Sposób, w jaki odbywa się w aplikacji jest bardzo prosta i właściwie zanieczyszcza kod z konstrukcji nieistotnych jak
int function (int param){
if(trace_level & LOG_FCALLS){
writelog("Entering function()");
}
/* something useful */
if(trace_level & LOG_FCALLS){
writelog("Exit from function()=%d", ret);
}
}
postanowiłem wykorzystać makro, które zrobi całą brudną robotę. Teraz wygląda to tak
#define LOG_E(fn) const char *__fname=fn; printf("LOG: Entry to %s\n",__fname)
#define return(ret) printf("LOG: Exit from %s()=%d\n",__fname,ret)
int testFunc(){
LOG_E("testFunc");
/*do useful things */
return(ret);
}
widzę problemów z tym kodem
mam nadrzędne return, a to wymaga, aby napisać
return(ret)
cały czas zamiastreturn ret
. Łatwo jest zapomnieć o tym problemie.Definiuję zmienną łańcuchową w moim makrze. Jestem świadomy, że makro istnieje w C99, ale mój kompilator niestety nie obsługuje tego makra ani żadnych innych istotnych makr.
Jak rejestrować wartości argumentów funkcji?
Jestem pewien, że to nie jest nowy problem i nie jestem pierwszym, który stanął przed tym. Jestem również świadomy rzeczy AOP, ale oprzyrządowanie kodu jest niedopuszczalne rozwiązanie dla mojego systemu i nie znalazłem żadnej możliwości, aby to zrobić z moim kompilatorem.
Poszukuję więc dobrych pomysłów, jak zaimplementować śledzenie w najbardziej elegancki sposób.
Moja okolica: kod Legacy, C, Watcom 10.x, OS czasu rzeczywistego
Co z tego, że w rzeczywistości nie wróci w ogóle? tzn. twój 'return (ret)' jest zjedzony przez makro i zamieniony na 'printf', a następnie funkcja nie ma instrukcji return do wykonania. Nie powracasz w tym makrze. – ArjunShankar
Watcom C obsługuje makro '__FUNCTION__'. – Matt
Na wypadek gdybyś przetestował istnienie '__func__' przez' # ifdef': To nie jest makro, ale statyczna tablica (jak gdyby została zadeklarowana z 'static cosnt char __func __ [] =" ... "; 'na początku funkcji). – mafso