SlideShare a Scribd company logo
1 of 53
La salute del Software
Prevenire è meglio che curare

Guido Pederzini

Marco Arena
Chi siamo
Guido Pederzini

Marco Arena

Ingegnere Informatico, 36 anni, di Modena

Ingegnere Informatico, 26 anni, di Roma

Appassionato di sicurezza informatica,
ambito in cui ha conseguito un master
universitario

Creatore di ++it, la comunità Italiana
dedicata al C++

Dal 2008, lavora in un team agile del
mondo della Formula 1

italiancpp.org
Dal 2011, lavora in un team agile del
mondo della Formula 1
Premesse
●

●

Il talk odierno è all' 80% frutto di esperienze di
team, al 20% di spunti di “ricerca”.
Focalizzeremo le soluzioni in ambiente
Windows, fatto salvo che i principi valgano
indipendentemente dalla piattaforma.
Outline
●

Introduzione

●

Prevenzione

●

Intercettare consumo di memoria

●

Intercettare degradi di performance

●

Intercettare difetti di coding

●

Affidabilità

●

Scegliere pragmaticamente
Introduzione
●

●

Un software può essere paragonato ad un
organismo vivente, nel quale tutte le parti
devono convivere armoniosamente e
cooperare, allo scopo di garantirne la
funzionalità: la vita.
Un software è tuttavia piuttosto meccanico,
la vera anima è rappresentata dal team di
sviluppatori.
Introduzione (2)
●

●

●

L'anima del software, ovvero il team, agisce
per garantire la funzionalità e quindi le
features, aumentando la superficie di
scambio fra il software e l'utente finale.
Il team, però, si preoccupa dello stato di
salute dell'organismo che sta evolvendo?
Abbiamo una propensione solo architetturale
o anche “medica”?
Prevenzione
●

●

La prima mela che rimbalzò nelle case di tutti
noi (molto prima dell'avvento di quella più
famosa che oggi troviamo ovunque) fu quella
che ricordava come “prevenire è meglio che
curare”.
Ma quando dobbiamo fare prevenzione nel
software? Quotidianamente!
Paradosso universitario

“Avendo risorse infinite, progettare un software
che realizzi, …”
- Prof. Ovvio
Paradosso universitario
●

●

●

Nella realtà non si hanno risorse infinite!
L'organismo dispone di risorse finite
Non solo: vanno anche condivise con altri
software / organismi
…

Come fare?
Sviluppo
Analisi

Design

Coding

Test

Prodotto Software

Deploy
Sviluppo
Analisi

Design

Coding

Test

Prodotto Software

???

Deploy
Sviluppo
Analisi

Design

Coding

Test

Deploy

Prodotto Software
Filesystem

CPUs

RAM
…

SO
SO’ greche!
L'affanno
●

●

●

●

Un organismo sano non è mai in affanno,
anche dopo uno sforzo fisico, recupera.
Un software dopo uno “sforzo” recupera?
Caso tipico: applicazione che dopo un uso
prolungato “scoppia”.
Cosa abbiamo sbagliato? Il design? Il test? Il
deploy? Forse più semplicemente possiamo
aver introdotto un memory leak!
L'affanno (2)
●

●

Un memory leak in un'applicazione legacy
può essere complicato da scovare.
Abbiamo alcuni modi per accorgersi del
problema, esempi:
–

Utilizzo della direttiva DEBUG_NEW

–

Utilizzo di strumenti come Visual Leak Detector

–

GTEST & Memory Leak Listener
L'affanno (3)

Live Demo: Memory Leak Listener
La prestazione
●

●

●

Un organismo sano e allenato sarà sempre
competitivo, immaginiamo in questo caso
un'analogia puramente sportiva.
Abbiamo
un
software
competitivo
relativamente ai requisiti che il nostro
business ci richiede?
Abbiamo utenti che percepiscono variazioni
di prestazione del software anche minimali?
La prestazione (2)
●

●

●

Dobbiamo accorgerci il prima possibile se il
software ha subito un degrado di
performance.
In questo modo possiamo minimizzare I tempi
necessari a scovare il changeset incriminato
Questo grazie a test di performances
assertivi e indicazioni sulla storia e sul trend
La prestazione (3)
●

Misurando il passato possiamo stimare:
–
–

●

come si potrebbe evolvere il futuro;
se una certa tecnologia/implementazione può rendere il
nostro software più prestazionale, più pronto.

In mancanza di questo possiamo parlare solo
di sensazioni o di ipotesi, prolungando
oltremodo la ricerca del problema.
Misurare sempre!!!
Un consiglio che mi sento di dare è: misurare
●

●

●

Dotatevi di un sistema, anche semplice, che
possa fornirvi misure sulle performances.
(QueryPerformanceCounter)
Cominciate dalle parti critiche.
Non date troppo spazio alle sensazioni o alle
religioni, ma supportatele sempre con dei
numeri. Avrete cosi in mano indicatori
inconfutabili sulla prestazione!
Grafici e CI

Live Demo: PRNG Performance
Grafici e CI

Trend per changeset

Trend medio per data (1 mese)
Il pane quotidiano
●

●

●

Per restare in forma quotidianamente
dobbiamo seguire delle regole.
“Non lasciatevi andare a facili costumi”!
Non bisogna trascurare la fase che va tra
l'ideazione di una feature e il suo riscontro
operativo (il nostro “pane quotidiano”).
La fase di attesa
●

●

Un progetto complesso può richiedere tempi
di attesa piuttosto elevati per portare a
termine la compilazione, in particolare a
causa di progetti nativi o scarso uso di
dipendenze binarie.
La
compilazione
onerosa
rende
lo
sviluppatore meno libero, fa perdere
produttività, ma può essere causa di
malessere interno se trascurata.
Il compilatore
●

●

Il compilatore è un amico che ci aiuta a
perseguire la salute del software.
In particolare fornisce almeno 3 strumenti
che possiamo utilizzare (sia per applicazioni
legacy che per progetti nuovi):
–

Warning as error

–

Static analysis e SAL
annotation language)

–

SDL (security development lifecycle)

(source

code
Warning level
●

●

In ambiente Microsoft abbiamo nei progetti
nativi 4 (+1) livelli di warning.
Quando faccio new project in VS2012 ho di
default:
–

W3 (livello di warning 3)

–

WX- (treat warnings as warnings)
E' sufficiente?
La risposta è ovviamente no!
●

●

●

Nella nostra esperienza abbiamo quindi
optato per una soluzione W4 (o /Wall) e
trattando i warnings come errori (/WX)
Questo
comporta
sicuramente
una
complessità iniziale: improvvisamente il
software presenta segnali di “malsanità”.
Ne vale la pena? Fino a quel momento tutto
girava...
Esempi
#pragma warning(disable:4996)
if (_stscanf((LPCSTR) line, _T("pane%d
= %d%"), &paneId, &Count)) {...}

Per non sostituire l'API insicura con l'API
secure, disabilitiamo il warning (che non ci
farebbe compilare) .
Ma stiamo nascondendo un bug di invalid
input format!
A volte è arduo (C4702)
#include <afxwin.h>
and standard components

// MFC core

#pragma warning (once:4702)

Questo è stato un po più complicato da
abilitare a causa di un bug su MFC. Ma è stato
molto utile , previene l'unreachable code
//if(something)
return;
other stuff;
A volte non piace (C4100)
int foo(int a, int b)
{ return a*2; }
●

●

Un parametro non utilizzato causa warning
che potrebbero risultare noiosi (es. null
object).
Ma piuttosto meglio andare puntuali sul
problema, la soluzione potrebbe essere
disabilitare il singolo warning se nel nostro
contesto non serve.
White list e centralizzazione
●

●

Utilizzando un approccio whitelist abbiamo
centralizzato le eccezioni (ovvero i warning
disabilitati) in modo da ricordarci gli sconti
fatti, all'interno di un unico header.
Abbiamo confinato i problemi del codice
legacy (che dovremo curare) e cerchiamo di
far crescere il nuovo codice in modo sano.
Static analysis
●

●

●

Mette a disposizione un'altra batteria di
warning che vengono intercettati solo
abilitando il flag /analyze.
Ha il difetto che rallenta la compilazione.
Intercetta problemi anche nei big (vedi gtest,
ppl.h).
Static analysis (2)
int *p = new int[10]; delete p; //
P *p = nullptr; p->a = 1;

Warning C6283

Warning C6011

{
int aa;
aa = 1; aa;
{
int aa; Warning C6246
aa = 2;
}
}

E via via tanti altri. Interessante l'uso di SAL (in
fase di studio)
SAL (attivo con /analyze)
_Check_return_ bool func()
{
return true;
}
void f()
{ func(); } //

Warning C6031

_Check_return_ int func_range(_In_range_(1, 3) int val) {return
val *2 ;}
if(func_range(4) > 1) {….} // Warning C28020

Annotando le funzioni possiamo imporre il
comportamento, bloccando la compilazione.
Utilizzato nel CRT.
SDL

●

VS2013 imposta di default SDL
Affidabilità
●

●

●

La prevenzione “statica” è un requisito
fondamentale per garantire l'affidabilità (e.g.
potenziale assenza di guasti) di un sistema.
In generale individua fattori di rischio (e.g. sintomi
di undefined behavior, funzioni unsecure, ...).
Ma il software, come sappiamo, è dinamico e
influenzato da tutte le interazioni che ha con
l'esterno (un po' come noi...).
Problemi di affidabilità
●

Interni (e.g. bug):
Per combatterli è importante fare prevenzione e
mantenere il software sotto controllo.

●

Esterni (e.g. hardware):
Più complicati e costosi da mitigare;
Vanno spesso accolti e gestiti internamente.
Ricette: precondizioni
●

●

Confine tra cause interne ed esterne.
Quali precondizioni hanno le librerie che sto
utilizzando?
–

●

Ad esempio, nelle STL i range non vengono
controllati

E quelle che sto esponendo al cliente dalla mia
API? E se mi passa un input non valido?
Ricette: log
●

Considerali anche per identificare:
–

Operazioni che hanno causato il problema;

–

Usi impropri del sistema (e.g. workaround);

–

Stato del sistema in determinate situazioni.

●

Log ad-hoc su alcuni utenti (“cimice”).

●

É importante avere un buon log-viewer.
Ricette: log
Ricette: crash

“Cosa farai per gestire eccezioni e crash?”
Ricette: crash

“Il software non deve crashare”
- Rambo
Ricette: crash
Ricette: crash-reporting
●

●

Un sistema di crash-reporting è un valido
alleato.
Questi sistemi di solito funzionano
attaccandosi ad alcuni handler messi a
disposizione dal linguaggio e dal sistema
operativo.
Crash-reporting in C++
●

●

●

Abbiamo fatto un po’ di esperimenti con Google
Breakpad (usato in Chrome, Mozilla, …).
Tool C++ cross-platform che genera minidump Windows
e stacktrace testuali.

Integrabile nel processo di continuous integration.
Crash-reporting in C++
bool dumpCallback(const wchar_t* dump_path, const wchar_t* minidump_id, void* context,
EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool succeeded)

{
LOG(FATAL) << "CRASH" << endl;
return succeeded;

}
int main(int argc, char* argv[])

{

google_breakpad::ExceptionHandler eh{L"C:temp",
nullptr, // filter
dumpCallback, // subito dopo che viene scritto il dump
nullptr, // context data
-1};

// esempi
volatile int* a = (int*)(NULL);
*a = 1; // access violation
auto i = 0;
auto ii = 1/i; // division by zero
std::vector<int> vec;
vec.push_back(1);
auto dontDoThis = vec[3]; // out of bounds

}
Crash-reporting in C++
Ricette: crash & design
●

Spesso un crash nasconde un problema di design…

IView* GetViewAtPosition(int){...}
while(...)
{
...
auto view = (SpecialView*)GetViewAtPosition(pos);
if (!view) // unsafe
continue;
...
}

// fix veloce
while(...)
{
...
auto view = dynamic_cast<SpecialView*>(GetViewAtPosition(pos));
if (!view) // più safe ma il problema di design rimane...
continue;
...
}
Tanta fortuna...
Drawback
●

●

●

Per i memory leak dobbiamo avere in CI la
doppia compilazione (anche debug)
Analisi di performances richiedono hardware
battezzato e identico a sè stesso
Il compile time è sempre motivo di
discussione
Conclusioni
●

●

●

●

●

Provare a prevenire ci aiuta a rilasciare con
più certezze
Un software sano non leakka
Un software sano ha ottimi livelli di
performance
Un software sano non si fa sconti a compile
time
Un software sano, è affidabile
Finale
●

●

Tutto ciò è stato possibile grazie ad un
processo agile, che ha la caratteristica di
durare da diversi anni, e che ha raccolto idee
di tante validissime persone
Jonathan Penn @jonathanpenn 30 Ott2013
“Advice to new programmers: Learning how
to triage is far more important than learning
clever frameworks”
Grazie a tutti!

More Related Content

What's hot

Scrum! Sopravvivere e gestire progetti tra polli, maiali e clienti
Scrum! Sopravvivere e gestire progetti tra polli, maiali e clientiScrum! Sopravvivere e gestire progetti tra polli, maiali e clienti
Scrum! Sopravvivere e gestire progetti tra polli, maiali e clientiMarco Da Rin Zanco
 
Introduzione alle metodologie e pratiche Agili ... ma l'agile c'entra qualcos...
Introduzione alle metodologie e pratiche Agili ... ma l'agile c'entra qualcos...Introduzione alle metodologie e pratiche Agili ... ma l'agile c'entra qualcos...
Introduzione alle metodologie e pratiche Agili ... ma l'agile c'entra qualcos...Roberto Bettazzoni
 
Agile e Lean Management
 Agile e Lean Management Agile e Lean Management
Agile e Lean ManagementSimone Onofri
 
Redistributable Intro To Scrum Ita
Redistributable Intro To Scrum ItaRedistributable Intro To Scrum Ita
Redistributable Intro To Scrum ItaLuciano Benetti
 
Scrum? E' come fare il bucato!
Scrum? E' come fare il bucato!Scrum? E' come fare il bucato!
Scrum? E' come fare il bucato!Manuel Scapolan
 
Agile Project Framework
Agile Project FrameworkAgile Project Framework
Agile Project FrameworkSimone Onofri
 
2014 07-08 7° webinar pmi-rome agile scrum
2014 07-08 7° webinar pmi-rome agile scrum2014 07-08 7° webinar pmi-rome agile scrum
2014 07-08 7° webinar pmi-rome agile scrumEmiliano Soldi
 
Open Innovation Campus - 05/04/2018 - Agile challenges: essere agili nello sv...
Open Innovation Campus - 05/04/2018 - Agile challenges: essere agili nello sv...Open Innovation Campus - 05/04/2018 - Agile challenges: essere agili nello sv...
Open Innovation Campus - 05/04/2018 - Agile challenges: essere agili nello sv...Vittorio Polizzi
 
Agile Project Management
Agile Project ManagementAgile Project Management
Agile Project ManagementGiulio Roggero
 
Sviluppo Agile secondo l'approccio SCRUM
Sviluppo Agile secondo l'approccio SCRUMSviluppo Agile secondo l'approccio SCRUM
Sviluppo Agile secondo l'approccio SCRUMMatteo Papadopoulos
 
5 scrum dalle trincee - principi agili
5   scrum dalle trincee - principi agili5   scrum dalle trincee - principi agili
5 scrum dalle trincee - principi agiliAlessio Del Toro
 
Agile Lean Conference 2016 - Paragano_Agile per vincere le resistenze
Agile Lean Conference 2016 - Paragano_Agile per vincere le resistenzeAgile Lean Conference 2016 - Paragano_Agile per vincere le resistenze
Agile Lean Conference 2016 - Paragano_Agile per vincere le resistenzeAgile Lean Conference
 
Agile Lean Management - MoSCoW, Timeboxing e Kanban
Agile Lean Management - MoSCoW, Timeboxing e KanbanAgile Lean Management - MoSCoW, Timeboxing e Kanban
Agile Lean Management - MoSCoW, Timeboxing e KanbanSimone Onofri
 

What's hot (20)

Dal waterfall allo scrum
Dal waterfall allo scrumDal waterfall allo scrum
Dal waterfall allo scrum
 
Scrum! Sopravvivere e gestire progetti tra polli, maiali e clienti
Scrum! Sopravvivere e gestire progetti tra polli, maiali e clientiScrum! Sopravvivere e gestire progetti tra polli, maiali e clienti
Scrum! Sopravvivere e gestire progetti tra polli, maiali e clienti
 
Introduzione alle metodologie e pratiche Agili ... ma l'agile c'entra qualcos...
Introduzione alle metodologie e pratiche Agili ... ma l'agile c'entra qualcos...Introduzione alle metodologie e pratiche Agili ... ma l'agile c'entra qualcos...
Introduzione alle metodologie e pratiche Agili ... ma l'agile c'entra qualcos...
 
Agile e Lean Management
 Agile e Lean Management Agile e Lean Management
Agile e Lean Management
 
Lezione 1: I metodi agili
Lezione 1: I metodi agiliLezione 1: I metodi agili
Lezione 1: I metodi agili
 
Redistributable Intro To Scrum Ita
Redistributable Intro To Scrum ItaRedistributable Intro To Scrum Ita
Redistributable Intro To Scrum Ita
 
Scrum? E' come fare il bucato!
Scrum? E' come fare il bucato!Scrum? E' come fare il bucato!
Scrum? E' come fare il bucato!
 
Agile@core - Scrum
Agile@core - ScrumAgile@core - Scrum
Agile@core - Scrum
 
Semplicemente Agile
Semplicemente AgileSemplicemente Agile
Semplicemente Agile
 
Agile software lifecycle
Agile software lifecycleAgile software lifecycle
Agile software lifecycle
 
Agile Project Framework
Agile Project FrameworkAgile Project Framework
Agile Project Framework
 
Agile methodologies
Agile methodologiesAgile methodologies
Agile methodologies
 
2014 07-08 7° webinar pmi-rome agile scrum
2014 07-08 7° webinar pmi-rome agile scrum2014 07-08 7° webinar pmi-rome agile scrum
2014 07-08 7° webinar pmi-rome agile scrum
 
Introduzione a Scrum
Introduzione a ScrumIntroduzione a Scrum
Introduzione a Scrum
 
Open Innovation Campus - 05/04/2018 - Agile challenges: essere agili nello sv...
Open Innovation Campus - 05/04/2018 - Agile challenges: essere agili nello sv...Open Innovation Campus - 05/04/2018 - Agile challenges: essere agili nello sv...
Open Innovation Campus - 05/04/2018 - Agile challenges: essere agili nello sv...
 
Agile Project Management
Agile Project ManagementAgile Project Management
Agile Project Management
 
Sviluppo Agile secondo l'approccio SCRUM
Sviluppo Agile secondo l'approccio SCRUMSviluppo Agile secondo l'approccio SCRUM
Sviluppo Agile secondo l'approccio SCRUM
 
5 scrum dalle trincee - principi agili
5   scrum dalle trincee - principi agili5   scrum dalle trincee - principi agili
5 scrum dalle trincee - principi agili
 
Agile Lean Conference 2016 - Paragano_Agile per vincere le resistenze
Agile Lean Conference 2016 - Paragano_Agile per vincere le resistenzeAgile Lean Conference 2016 - Paragano_Agile per vincere le resistenze
Agile Lean Conference 2016 - Paragano_Agile per vincere le resistenze
 
Agile Lean Management - MoSCoW, Timeboxing e Kanban
Agile Lean Management - MoSCoW, Timeboxing e KanbanAgile Lean Management - MoSCoW, Timeboxing e Kanban
Agile Lean Management - MoSCoW, Timeboxing e Kanban
 

Viewers also liked

Agileday Coderetreat 2013
Agileday Coderetreat 2013Agileday Coderetreat 2013
Agileday Coderetreat 2013Gabriele Lana
 
From Vision To Product
From Vision To ProductFrom Vision To Product
From Vision To ProductStefano Leli
 
Outcome not Output: A Story of Lean UX Adoption
Outcome not Output: A Story of Lean UX AdoptionOutcome not Output: A Story of Lean UX Adoption
Outcome not Output: A Story of Lean UX AdoptionSteve Maraspin
 
One, No One, One Hundred Thousand Projects (Uno, Nessuno, Centomila Progetti)
One, No One, One Hundred Thousand Projects (Uno, Nessuno, Centomila Progetti)One, No One, One Hundred Thousand Projects (Uno, Nessuno, Centomila Progetti)
One, No One, One Hundred Thousand Projects (Uno, Nessuno, Centomila Progetti)Gaetano Mazzanti
 
When Tdd Goes Awry (IAD 2013)
When Tdd Goes Awry (IAD 2013)When Tdd Goes Awry (IAD 2013)
When Tdd Goes Awry (IAD 2013)Uberto Barbini
 
Se “Embrace Change” è difficile.
Se “Embrace Change” è difficile.Se “Embrace Change” è difficile.
Se “Embrace Change” è difficile.Fabio Mora
 

Viewers also liked (9)

Agileday Coderetreat 2013
Agileday Coderetreat 2013Agileday Coderetreat 2013
Agileday Coderetreat 2013
 
Bravi si diventa
Bravi si diventaBravi si diventa
Bravi si diventa
 
From Vision To Product
From Vision To ProductFrom Vision To Product
From Vision To Product
 
dalTDDalBDD
dalTDDalBDDdalTDDalBDD
dalTDDalBDD
 
Outcome not Output: A Story of Lean UX Adoption
Outcome not Output: A Story of Lean UX AdoptionOutcome not Output: A Story of Lean UX Adoption
Outcome not Output: A Story of Lean UX Adoption
 
One, No One, One Hundred Thousand Projects (Uno, Nessuno, Centomila Progetti)
One, No One, One Hundred Thousand Projects (Uno, Nessuno, Centomila Progetti)One, No One, One Hundred Thousand Projects (Uno, Nessuno, Centomila Progetti)
One, No One, One Hundred Thousand Projects (Uno, Nessuno, Centomila Progetti)
 
When Tdd Goes Awry (IAD 2013)
When Tdd Goes Awry (IAD 2013)When Tdd Goes Awry (IAD 2013)
When Tdd Goes Awry (IAD 2013)
 
Se “Embrace Change” è difficile.
Se “Embrace Change” è difficile.Se “Embrace Change” è difficile.
Se “Embrace Change” è difficile.
 
TDD anche su iOS
TDD anche su iOSTDD anche su iOS
TDD anche su iOS
 

Similar to La salute del software

AgileDay 2006 - Essere agili nel diventare agili
AgileDay 2006 - Essere agili nel diventare agiliAgileDay 2006 - Essere agili nel diventare agili
AgileDay 2006 - Essere agili nel diventare agiliLuca Minudel
 
Data Analysis & Machine Learning
Data Analysis & Machine LearningData Analysis & Machine Learning
Data Analysis & Machine LearningCaffeina
 
Corretta%20 manutenzione%20italiano[1]
Corretta%20 manutenzione%20italiano[1]Corretta%20 manutenzione%20italiano[1]
Corretta%20 manutenzione%20italiano[1]joglopa
 
Keep calm and deploy
Keep calm and deployKeep calm and deploy
Keep calm and deployKlab
 
AgileIoT, da Arduino al Delivery
AgileIoT, da Arduino al DeliveryAgileIoT, da Arduino al Delivery
AgileIoT, da Arduino al DeliveryFelice Pescatore
 
Keep calm and Deploy - Panoramica sui problemi che emergono in fase di rilasc...
Keep calm and Deploy - Panoramica sui problemi che emergono in fase di rilasc...Keep calm and Deploy - Panoramica sui problemi che emergono in fase di rilasc...
Keep calm and Deploy - Panoramica sui problemi che emergono in fase di rilasc...Andrea Cirioni
 
Una fugace occhiata al Test Driven Development (2006)
Una fugace occhiata al Test Driven Development  (2006)Una fugace occhiata al Test Driven Development  (2006)
Una fugace occhiata al Test Driven Development (2006)Roberto Bettazzoni
 
Stop Meeting, Start Coding!
Stop Meeting, Start Coding!Stop Meeting, Start Coding!
Stop Meeting, Start Coding!Giulio Roggero
 
Seminario di informatica 1
Seminario di informatica 1Seminario di informatica 1
Seminario di informatica 1Andrea Barilli
 
festival ICT 2013: Vivere open source dalle applicazioni ad arduino
festival ICT 2013: Vivere open source dalle applicazioni ad arduinofestival ICT 2013: Vivere open source dalle applicazioni ad arduino
festival ICT 2013: Vivere open source dalle applicazioni ad arduinofestival ICT 2016
 
Blockchain e AI: verso una nuova finanza
Blockchain e AI: verso una nuova finanzaBlockchain e AI: verso una nuova finanza
Blockchain e AI: verso una nuova finanzaAlessandro Greppi
 
Corso di Basi e Fondamenti di Programmazione in C++ Lezione 1
Corso di Basi e Fondamenti di Programmazione in C++ Lezione 1Corso di Basi e Fondamenti di Programmazione in C++ Lezione 1
Corso di Basi e Fondamenti di Programmazione in C++ Lezione 1Daniele Falamesca
 
Sperimentazione di Tecnologie di Deep Learning su Sistemi Embedded
Sperimentazione di Tecnologie di Deep Learning su Sistemi EmbeddedSperimentazione di Tecnologie di Deep Learning su Sistemi Embedded
Sperimentazione di Tecnologie di Deep Learning su Sistemi EmbeddedMathiasPoloPerucchin
 
Guida al Computer - Lezione 79 - Gli Aggiornamenti
Guida al Computer - Lezione 79 - Gli AggiornamentiGuida al Computer - Lezione 79 - Gli Aggiornamenti
Guida al Computer - Lezione 79 - Gli Aggiornamenticaioturtle
 
Ttg 09 07_2015_debug_vs_2015
Ttg 09 07_2015_debug_vs_2015Ttg 09 07_2015_debug_vs_2015
Ttg 09 07_2015_debug_vs_2015Piero Sbressa
 
Smau Milano 2019 AIPSI
Smau Milano 2019 AIPSISmau Milano 2019 AIPSI
Smau Milano 2019 AIPSISMAU
 

Similar to La salute del software (20)

AgileDay 2006 - Essere agili nel diventare agili
AgileDay 2006 - Essere agili nel diventare agiliAgileDay 2006 - Essere agili nel diventare agili
AgileDay 2006 - Essere agili nel diventare agili
 
Data Analysis & Machine Learning
Data Analysis & Machine LearningData Analysis & Machine Learning
Data Analysis & Machine Learning
 
Corretta%20 manutenzione%20italiano[1]
Corretta%20 manutenzione%20italiano[1]Corretta%20 manutenzione%20italiano[1]
Corretta%20 manutenzione%20italiano[1]
 
Software
SoftwareSoftware
Software
 
Keep calm and deploy
Keep calm and deployKeep calm and deploy
Keep calm and deploy
 
AgileIoT, da Arduino al Delivery
AgileIoT, da Arduino al DeliveryAgileIoT, da Arduino al Delivery
AgileIoT, da Arduino al Delivery
 
Keep calm and Deploy - Panoramica sui problemi che emergono in fase di rilasc...
Keep calm and Deploy - Panoramica sui problemi che emergono in fase di rilasc...Keep calm and Deploy - Panoramica sui problemi che emergono in fase di rilasc...
Keep calm and Deploy - Panoramica sui problemi che emergono in fase di rilasc...
 
I punti deboli del sistema ICT dello Studio - Giacomo Barbieri
I punti deboli del sistema ICT dello Studio - Giacomo BarbieriI punti deboli del sistema ICT dello Studio - Giacomo Barbieri
I punti deboli del sistema ICT dello Studio - Giacomo Barbieri
 
Una fugace occhiata al Test Driven Development (2006)
Una fugace occhiata al Test Driven Development  (2006)Una fugace occhiata al Test Driven Development  (2006)
Una fugace occhiata al Test Driven Development (2006)
 
Stop Meeting, Start Coding!
Stop Meeting, Start Coding!Stop Meeting, Start Coding!
Stop Meeting, Start Coding!
 
On demand Webinars
On demand WebinarsOn demand Webinars
On demand Webinars
 
Seminario di informatica 1
Seminario di informatica 1Seminario di informatica 1
Seminario di informatica 1
 
festival ICT 2013: Vivere open source dalle applicazioni ad arduino
festival ICT 2013: Vivere open source dalle applicazioni ad arduinofestival ICT 2013: Vivere open source dalle applicazioni ad arduino
festival ICT 2013: Vivere open source dalle applicazioni ad arduino
 
Blockchain e AI: verso una nuova finanza
Blockchain e AI: verso una nuova finanzaBlockchain e AI: verso una nuova finanza
Blockchain e AI: verso una nuova finanza
 
Corso di Basi e Fondamenti di Programmazione in C++ Lezione 1
Corso di Basi e Fondamenti di Programmazione in C++ Lezione 1Corso di Basi e Fondamenti di Programmazione in C++ Lezione 1
Corso di Basi e Fondamenti di Programmazione in C++ Lezione 1
 
Sperimentazione di Tecnologie di Deep Learning su Sistemi Embedded
Sperimentazione di Tecnologie di Deep Learning su Sistemi EmbeddedSperimentazione di Tecnologie di Deep Learning su Sistemi Embedded
Sperimentazione di Tecnologie di Deep Learning su Sistemi Embedded
 
Guida al Computer - Lezione 79 - Gli Aggiornamenti
Guida al Computer - Lezione 79 - Gli AggiornamentiGuida al Computer - Lezione 79 - Gli Aggiornamenti
Guida al Computer - Lezione 79 - Gli Aggiornamenti
 
Ttg 09 07_2015_debug_vs_2015
Ttg 09 07_2015_debug_vs_2015Ttg 09 07_2015_debug_vs_2015
Ttg 09 07_2015_debug_vs_2015
 
Introduzione ad Android
Introduzione ad AndroidIntroduzione ad Android
Introduzione ad Android
 
Smau Milano 2019 AIPSI
Smau Milano 2019 AIPSISmau Milano 2019 AIPSI
Smau Milano 2019 AIPSI
 

La salute del software

  • 1. La salute del Software Prevenire è meglio che curare Guido Pederzini Marco Arena
  • 2. Chi siamo Guido Pederzini Marco Arena Ingegnere Informatico, 36 anni, di Modena Ingegnere Informatico, 26 anni, di Roma Appassionato di sicurezza informatica, ambito in cui ha conseguito un master universitario Creatore di ++it, la comunità Italiana dedicata al C++ Dal 2008, lavora in un team agile del mondo della Formula 1 italiancpp.org Dal 2011, lavora in un team agile del mondo della Formula 1
  • 3. Premesse ● ● Il talk odierno è all' 80% frutto di esperienze di team, al 20% di spunti di “ricerca”. Focalizzeremo le soluzioni in ambiente Windows, fatto salvo che i principi valgano indipendentemente dalla piattaforma.
  • 4. Outline ● Introduzione ● Prevenzione ● Intercettare consumo di memoria ● Intercettare degradi di performance ● Intercettare difetti di coding ● Affidabilità ● Scegliere pragmaticamente
  • 5. Introduzione ● ● Un software può essere paragonato ad un organismo vivente, nel quale tutte le parti devono convivere armoniosamente e cooperare, allo scopo di garantirne la funzionalità: la vita. Un software è tuttavia piuttosto meccanico, la vera anima è rappresentata dal team di sviluppatori.
  • 6. Introduzione (2) ● ● ● L'anima del software, ovvero il team, agisce per garantire la funzionalità e quindi le features, aumentando la superficie di scambio fra il software e l'utente finale. Il team, però, si preoccupa dello stato di salute dell'organismo che sta evolvendo? Abbiamo una propensione solo architetturale o anche “medica”?
  • 7. Prevenzione ● ● La prima mela che rimbalzò nelle case di tutti noi (molto prima dell'avvento di quella più famosa che oggi troviamo ovunque) fu quella che ricordava come “prevenire è meglio che curare”. Ma quando dobbiamo fare prevenzione nel software? Quotidianamente!
  • 8. Paradosso universitario “Avendo risorse infinite, progettare un software che realizzi, …” - Prof. Ovvio
  • 9. Paradosso universitario ● ● ● Nella realtà non si hanno risorse infinite! L'organismo dispone di risorse finite Non solo: vanno anche condivise con altri software / organismi … Come fare?
  • 14. L'affanno ● ● ● ● Un organismo sano non è mai in affanno, anche dopo uno sforzo fisico, recupera. Un software dopo uno “sforzo” recupera? Caso tipico: applicazione che dopo un uso prolungato “scoppia”. Cosa abbiamo sbagliato? Il design? Il test? Il deploy? Forse più semplicemente possiamo aver introdotto un memory leak!
  • 15. L'affanno (2) ● ● Un memory leak in un'applicazione legacy può essere complicato da scovare. Abbiamo alcuni modi per accorgersi del problema, esempi: – Utilizzo della direttiva DEBUG_NEW – Utilizzo di strumenti come Visual Leak Detector – GTEST & Memory Leak Listener
  • 16. L'affanno (3) Live Demo: Memory Leak Listener
  • 17. La prestazione ● ● ● Un organismo sano e allenato sarà sempre competitivo, immaginiamo in questo caso un'analogia puramente sportiva. Abbiamo un software competitivo relativamente ai requisiti che il nostro business ci richiede? Abbiamo utenti che percepiscono variazioni di prestazione del software anche minimali?
  • 18. La prestazione (2) ● ● ● Dobbiamo accorgerci il prima possibile se il software ha subito un degrado di performance. In questo modo possiamo minimizzare I tempi necessari a scovare il changeset incriminato Questo grazie a test di performances assertivi e indicazioni sulla storia e sul trend
  • 19. La prestazione (3) ● Misurando il passato possiamo stimare: – – ● come si potrebbe evolvere il futuro; se una certa tecnologia/implementazione può rendere il nostro software più prestazionale, più pronto. In mancanza di questo possiamo parlare solo di sensazioni o di ipotesi, prolungando oltremodo la ricerca del problema.
  • 20. Misurare sempre!!! Un consiglio che mi sento di dare è: misurare ● ● ● Dotatevi di un sistema, anche semplice, che possa fornirvi misure sulle performances. (QueryPerformanceCounter) Cominciate dalle parti critiche. Non date troppo spazio alle sensazioni o alle religioni, ma supportatele sempre con dei numeri. Avrete cosi in mano indicatori inconfutabili sulla prestazione!
  • 21. Grafici e CI Live Demo: PRNG Performance
  • 22. Grafici e CI Trend per changeset Trend medio per data (1 mese)
  • 23. Il pane quotidiano ● ● ● Per restare in forma quotidianamente dobbiamo seguire delle regole. “Non lasciatevi andare a facili costumi”! Non bisogna trascurare la fase che va tra l'ideazione di una feature e il suo riscontro operativo (il nostro “pane quotidiano”).
  • 24. La fase di attesa ● ● Un progetto complesso può richiedere tempi di attesa piuttosto elevati per portare a termine la compilazione, in particolare a causa di progetti nativi o scarso uso di dipendenze binarie. La compilazione onerosa rende lo sviluppatore meno libero, fa perdere produttività, ma può essere causa di malessere interno se trascurata.
  • 25. Il compilatore ● ● Il compilatore è un amico che ci aiuta a perseguire la salute del software. In particolare fornisce almeno 3 strumenti che possiamo utilizzare (sia per applicazioni legacy che per progetti nuovi): – Warning as error – Static analysis e SAL annotation language) – SDL (security development lifecycle) (source code
  • 26. Warning level ● ● In ambiente Microsoft abbiamo nei progetti nativi 4 (+1) livelli di warning. Quando faccio new project in VS2012 ho di default: – W3 (livello di warning 3) – WX- (treat warnings as warnings)
  • 27. E' sufficiente? La risposta è ovviamente no! ● ● ● Nella nostra esperienza abbiamo quindi optato per una soluzione W4 (o /Wall) e trattando i warnings come errori (/WX) Questo comporta sicuramente una complessità iniziale: improvvisamente il software presenta segnali di “malsanità”. Ne vale la pena? Fino a quel momento tutto girava...
  • 28. Esempi #pragma warning(disable:4996) if (_stscanf((LPCSTR) line, _T("pane%d = %d%"), &paneId, &Count)) {...} Per non sostituire l'API insicura con l'API secure, disabilitiamo il warning (che non ci farebbe compilare) . Ma stiamo nascondendo un bug di invalid input format!
  • 29. A volte è arduo (C4702) #include <afxwin.h> and standard components // MFC core #pragma warning (once:4702) Questo è stato un po più complicato da abilitare a causa di un bug su MFC. Ma è stato molto utile , previene l'unreachable code //if(something) return; other stuff;
  • 30. A volte non piace (C4100) int foo(int a, int b) { return a*2; } ● ● Un parametro non utilizzato causa warning che potrebbero risultare noiosi (es. null object). Ma piuttosto meglio andare puntuali sul problema, la soluzione potrebbe essere disabilitare il singolo warning se nel nostro contesto non serve.
  • 31. White list e centralizzazione ● ● Utilizzando un approccio whitelist abbiamo centralizzato le eccezioni (ovvero i warning disabilitati) in modo da ricordarci gli sconti fatti, all'interno di un unico header. Abbiamo confinato i problemi del codice legacy (che dovremo curare) e cerchiamo di far crescere il nuovo codice in modo sano.
  • 32. Static analysis ● ● ● Mette a disposizione un'altra batteria di warning che vengono intercettati solo abilitando il flag /analyze. Ha il difetto che rallenta la compilazione. Intercetta problemi anche nei big (vedi gtest, ppl.h).
  • 33. Static analysis (2) int *p = new int[10]; delete p; // P *p = nullptr; p->a = 1; Warning C6283 Warning C6011 { int aa; aa = 1; aa; { int aa; Warning C6246 aa = 2; } } E via via tanti altri. Interessante l'uso di SAL (in fase di studio)
  • 34. SAL (attivo con /analyze) _Check_return_ bool func() { return true; } void f() { func(); } // Warning C6031 _Check_return_ int func_range(_In_range_(1, 3) int val) {return val *2 ;} if(func_range(4) > 1) {….} // Warning C28020 Annotando le funzioni possiamo imporre il comportamento, bloccando la compilazione. Utilizzato nel CRT.
  • 36. Affidabilità ● ● ● La prevenzione “statica” è un requisito fondamentale per garantire l'affidabilità (e.g. potenziale assenza di guasti) di un sistema. In generale individua fattori di rischio (e.g. sintomi di undefined behavior, funzioni unsecure, ...). Ma il software, come sappiamo, è dinamico e influenzato da tutte le interazioni che ha con l'esterno (un po' come noi...).
  • 37. Problemi di affidabilità ● Interni (e.g. bug): Per combatterli è importante fare prevenzione e mantenere il software sotto controllo. ● Esterni (e.g. hardware): Più complicati e costosi da mitigare; Vanno spesso accolti e gestiti internamente.
  • 38. Ricette: precondizioni ● ● Confine tra cause interne ed esterne. Quali precondizioni hanno le librerie che sto utilizzando? – ● Ad esempio, nelle STL i range non vengono controllati E quelle che sto esponendo al cliente dalla mia API? E se mi passa un input non valido?
  • 39. Ricette: log ● Considerali anche per identificare: – Operazioni che hanno causato il problema; – Usi impropri del sistema (e.g. workaround); – Stato del sistema in determinate situazioni. ● Log ad-hoc su alcuni utenti (“cimice”). ● É importante avere un buon log-viewer.
  • 41. Ricette: crash “Cosa farai per gestire eccezioni e crash?”
  • 42. Ricette: crash “Il software non deve crashare” - Rambo
  • 44. Ricette: crash-reporting ● ● Un sistema di crash-reporting è un valido alleato. Questi sistemi di solito funzionano attaccandosi ad alcuni handler messi a disposizione dal linguaggio e dal sistema operativo.
  • 45. Crash-reporting in C++ ● ● ● Abbiamo fatto un po’ di esperimenti con Google Breakpad (usato in Chrome, Mozilla, …). Tool C++ cross-platform che genera minidump Windows e stacktrace testuali. Integrabile nel processo di continuous integration.
  • 46. Crash-reporting in C++ bool dumpCallback(const wchar_t* dump_path, const wchar_t* minidump_id, void* context, EXCEPTION_POINTERS* exinfo, MDRawAssertionInfo* assertion, bool succeeded) { LOG(FATAL) << "CRASH" << endl; return succeeded; } int main(int argc, char* argv[]) { google_breakpad::ExceptionHandler eh{L"C:temp", nullptr, // filter dumpCallback, // subito dopo che viene scritto il dump nullptr, // context data -1}; // esempi volatile int* a = (int*)(NULL); *a = 1; // access violation auto i = 0; auto ii = 1/i; // division by zero std::vector<int> vec; vec.push_back(1); auto dontDoThis = vec[3]; // out of bounds }
  • 48. Ricette: crash & design ● Spesso un crash nasconde un problema di design… IView* GetViewAtPosition(int){...} while(...) { ... auto view = (SpecialView*)GetViewAtPosition(pos); if (!view) // unsafe continue; ... } // fix veloce while(...) { ... auto view = dynamic_cast<SpecialView*>(GetViewAtPosition(pos)); if (!view) // più safe ma il problema di design rimane... continue; ... }
  • 50. Drawback ● ● ● Per i memory leak dobbiamo avere in CI la doppia compilazione (anche debug) Analisi di performances richiedono hardware battezzato e identico a sè stesso Il compile time è sempre motivo di discussione
  • 51. Conclusioni ● ● ● ● ● Provare a prevenire ci aiuta a rilasciare con più certezze Un software sano non leakka Un software sano ha ottimi livelli di performance Un software sano non si fa sconti a compile time Un software sano, è affidabile
  • 52. Finale ● ● Tutto ciò è stato possibile grazie ad un processo agile, che ha la caratteristica di durare da diversi anni, e che ha raccolto idee di tante validissime persone Jonathan Penn @jonathanpenn 30 Ott2013 “Advice to new programmers: Learning how to triage is far more important than learning clever frameworks”

Editor's Notes

  1. &lt;numero&gt;
  2. &lt;numero&gt;
  3. Memory leak listener CRT DEBUG (VS) Build automatica (con pro e contro) Strumenti più evoluti (e.g. Visual Leak Detector) &lt;numero&gt;
  4. Memory leak listener CRT DEBUG (VS) Build automatica (con pro e contro) Strumenti più evoluti (e.g. Visual Leak Detector) &lt;numero&gt;
  5. Memory leak listener CRT DEBUG (VS) Build automatica (con pro e contro) Strumenti più evoluti (e.g. Visual Leak Detector) &lt;numero&gt;
  6. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  7. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  8. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  9. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  10. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  11. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  12. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  13. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  14. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  15. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  16. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  17. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  18. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  19. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  20. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  21. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  22. Sempre in base a necessità &amp; contesto No ottimizzazione preventiva Misure tempo feature consolidate + trend (macchine dedicate) Utente nota le lentezze e quando variano Misure &amp; Test, strumenti di build automatica (e.g. TC) «The free lunch is over» (non basta più comprare nuovo hw) Codice performance a volte fa a cazzotti con il design classico (tradeoff) &lt;numero&gt;
  23. Monitorare la vita di un’applicazione Intercettare problemi (e.g. log-faces) Occhio a non loggare troppo (performance) &lt;numero&gt;
  24. Monitorare la vita di un’applicazione Intercettare problemi (e.g. log-faces) Occhio a non loggare troppo (performance) &lt;numero&gt;
  25. Monitorare la vita di un’applicazione Intercettare problemi (e.g. log-faces) Occhio a non loggare troppo (performance) &lt;numero&gt;
  26. Monitorare la vita di un’applicazione Intercettare problemi (e.g. log-faces) Occhio a non loggare troppo (performance) &lt;numero&gt;
  27. Monitorare la vita di un’applicazione Intercettare problemi (e.g. log-faces) Occhio a non loggare troppo (performance) &lt;numero&gt;