Arduino-Debug
On-target sketch debugger for Arduino
Debug.h
Go to the documentation of this file.
1 
19 #ifndef DEBUG_H
20 #define DEBUG_H
21 
22 #include "Arduino.h"
23 
24 #ifndef UNUSED
25 #define UNUSED(x) (void) (x)
26 #endif
27 
28 #ifndef UNLIKELY
29 #define UNLIKELY(x) __builtin_expect((x), false)
30 #endif
31 
32 typedef const class __FlashStringHelper* str_P;
33 
34 extern class Debug debug;
35 
55 class Debug : public Stream {
56 public:
60  Debug() :
61  Stream(),
62  m_dev(NULL),
63  m_var(NULL)
64  {}
65 
76  bool begin(Stream* dev,
77  const char* file,
78  int line,
79  const char* func);
80 
90  void assert(const char* file,
91  int line,
92  const char* func,
93  str_P cond);
94 
104  void break_at(const char* file,
105  int line,
106  const char* func,
107  str_P cond);
108 
115  bool check_stack(int room = 128);
116 
126  void observe_at(const char* file,
127  int line,
128  const char* func,
129  str_P expr);
130 
135  bool end();
136 
142  class Variable {
143  public:
148  Variable(const char* func, str_P name, void* ref, size_t size) :
149  m_next(debug.m_var),
150  m_func(func),
151  m_name(name),
152  m_ref(ref),
153  m_size(size)
154  {
155  debug.m_var = this;
156  }
157 
163  {
164  debug.m_var = m_next;
165  }
166 
171  void print(bool is_pointer = false);
172 
173  protected:
174  friend class Debug;
175  class Variable* m_next;
176  const char* m_func;
178  void* m_ref;
179  size_t m_size;
180  };
181 
182 protected:
183  virtual size_t write(uint8_t c) { return (m_dev->write(c)); }
184  virtual int available(void) { return (m_dev->available()); }
185  virtual int peek(void) { return (m_dev->peek()); }
186  virtual int read(void) { return (m_dev->read()); }
187  virtual void flush(void) { m_dev->flush(); }
188 
195  void dump(uint16_t src, const void *ptr, size_t size);
196 
204  void run(const char* file = NULL,
205  int line = 0,
206  const char* func = NULL,
207  str_P expr = NULL);
208 
209 #if !defined(DEBUG_NO_BACKTRACE)
210 
214  void do_backtrace(const char* func);
215 #endif
216 
217 #if !defined(DEBUG_NO_LOOKUP_VARIABLES)
218 
224  bool do_lookup_variables(const char* name, bool is_pointer = false);
225 #endif
226 
227 #if !defined(DEBUG_NO_MEMORY_USAGE)
228 
232  void do_memory_usage(int marker);
233 #endif
234 
235 #if !defined(DEBUG_NO_PRINT_COMMANDS)
236 
239  void do_print_commands();
240 #endif
241 
242 #if !defined(DEBUG_NO_PRINT_DATA)
243 
246  void do_print_data();
247 #endif
248 
249 #if !defined(DEBUG_NO_PRINT_HEAP)
250 
253  void do_print_heap();
254 #endif
255 
256 #if !defined(DEBUG_NO_PRINT_STACK)
257 
260  void do_print_stack(int marker);
261 #endif
262 
263 #if !defined(DEBUG_NO_PRINT_VARIABLES)
264 
275  void do_print_variables();
276 #endif
277 
278 #if !defined(DEBUG_NO_QUIT)
279 
282  void do_quit();
283 #endif
284 
285  friend class Variable;
286  Stream* m_dev;
288  int DATAEND;
289  int DATASIZE;
290 };
291 
292 #if !defined(NDEBUG)
293 
299 #define DEBUG_STREAM(dev) \
300  do { \
301  debug.begin(&dev, __FILE__,__LINE__, __PRETTY_FUNCTION__); \
302  } while (0)
303 
304 #if defined(ASSERT)
305 #undef ASSERT
306 #endif
307 
313 #define ASSERT(cond) \
314  do { \
315  if (UNLIKELY(!(cond))) \
316  debug.assert(__FILE__,__LINE__, __PRETTY_FUNCTION__, \
317  F(# cond)); \
318  } while (0)
319 
325 #define BREAKPOINT() \
326  do { \
327  debug.break_at(__FILE__,__LINE__, __PRETTY_FUNCTION__, NULL); \
328  } while (0)
329 
336 #define BREAK_IF(cond) \
337  do { \
338  if (UNLIKELY(cond)) \
339  debug.break_at(__FILE__,__LINE__, __PRETTY_FUNCTION__, \
340  F(# cond)); \
341  } while (0)
342 
347 #define CHECK_STACK(room) \
348  do { \
349  if (UNLIKELY(!(debug.check_stack(room)))) \
350  debug.assert(__FILE__,__LINE__, __PRETTY_FUNCTION__, \
351  F("check_stack()")); \
352  } while (0)
353 
360 #define OBSERVE_IF(cond,expr) \
361  do { \
362  if (UNLIKELY(cond)) { \
363  debug.observe_at(__FILE__,__LINE__, __PRETTY_FUNCTION__, \
364  F(# expr)); \
365  debug.println(expr); \
366  } \
367  } while (0)
368 
373 #define OBSERVE(expr) OBSERVE_IF(true,expr)
374 
381 #define REGISTER(var) \
382  Debug::Variable debug__ ## var(__PRETTY_FUNCTION__, \
383  F(#var), \
384  (void*) &var, \
385  sizeof(var));
386 
387 #else
388 
389 #if !defined(ASSERT)
390 #define ASSERT(cond) do { if (!(cond)) exit(0); } while (0)
391 #endif
392 #define BREAKPOINT()
393 #define BREAK_IF(cond)
394 #define CHECK_STACK(room)
395 #define DEBUG_STREAM(dev)
396 #define OBSERVE_IF(cond,expr)
397 #define OBSERVE(expr)
398 #define REGISTER(var)
399 
400 #endif
401 #endif
void c()
Definition: DebugDemo.ino:68
virtual void flush(void)
Definition: Debug.h:187
const class __FlashStringHelper * str_P
Definition: Debug.h:32
void do_quit()
void do_print_heap()
Definition: Debug.cpp:329
void run(const char *file=NULL, int line=0, const char *func=NULL, str_P expr=NULL)
Definition: Debug.cpp:104
void do_print_stack(int marker)
Definition: Debug.cpp:341
bool check_stack(int room=128)
Definition: Debug.cpp:69
Debug()
Definition: Debug.h:60
void observe_at(const char *file, int line, const char *func, str_P expr)
Definition: Debug.cpp:78
void do_print_variables()
Definition: Debug.cpp:351
const char * m_func
Registered in function.
Definition: Debug.h:176
bool begin(Stream *dev, const char *file, int line, const char *func)
Definition: Debug.cpp:29
void do_backtrace(const char *func)
Definition: Debug.cpp:234
void assert(const char *file, int line, const char *func, str_P cond)
Definition: Debug.cpp:47
bool end()
Definition: Debug.cpp:94
Variable * m_var
Last registered variable.
Definition: Debug.h:287
void do_print_data()
Definition: Debug.cpp:321
virtual int read(void)
Definition: Debug.h:186
void do_print_commands()
Definition: Debug.cpp:282
void print(bool is_pointer=false)
Definition: Debug.cpp:358
void dump(uint16_t src, const void *ptr, size_t size)
Definition: Debug.cpp:397
Stream * m_dev
Debug stream.
Definition: Debug.h:286
void do_memory_usage(int marker)
Definition: Debug.cpp:266
int DATAEND
End of data segment.
Definition: Debug.h:288
void break_at(const char *file, int line, const char *func, str_P cond)
Definition: Debug.cpp:59
Variable(const char *func, str_P name, void *ref, size_t size)
Definition: Debug.h:148
int DATASIZE
Size of data segment.
Definition: Debug.h:289
class Debug debug
Definition: Debug.cpp:24
void * m_ref
Variable value reference.
Definition: Debug.h:178
bool do_lookup_variables(const char *name, bool is_pointer=false)
Definition: Debug.cpp:250
Definition: Debug.h:55
virtual int peek(void)
Definition: Debug.h:185
virtual size_t write(uint8_t c)
Definition: Debug.h:183
size_t m_size
Variable value size.
Definition: Debug.h:179
virtual int available(void)
Definition: Debug.h:184
class Variable * m_next
Next variable.
Definition: Debug.h:175
str_P m_name
Function name.
Definition: Debug.h:177