Commit 3707c6ee0d1f939130a62c945b56045d9a83fafc

Authored by Simon Glass
1 parent 8cb7c04248

log: Add a way to log error-return values

When functions return an error it propagates up the stack to the point
where it is reported. Often the error code provides enough information
about the root cause of the error that this is obvious what went wrong.

However in some cases the error may be hard to trace. For example if a
driver uses several devices to perform an operation, it may not be
obvious which one failed.

Add a log_ret() macro to help with this. This can be used to wrap any
error-return value. The logging system will then output a log record when
the original error is generated, making it easy to trace the call stack
of the error.

This macro can significantly impact code size, so its use is controlled
by a Kconfig option, which is enabled for sandbox.

Signed-off-by: Simon Glass <sjg@chromium.org>

Showing 4 changed files with 33 additions and 0 deletions Side-by-side Diff

... ... @@ -504,6 +504,19 @@
504 504 in various different ways to test that the logging system works
505 505 correctly with varoius settings.
506 506  
  507 +config LOG_ERROR_RETURN
  508 + bool "Log all functions which return an error"
  509 + depends on LOG
  510 + help
  511 + When an error is returned in U-Boot it is sometimes difficult to
  512 + figure out the root cause. For eaxmple, reading from SPI flash may
  513 + fail due to a problem in the SPI controller or due to the flash part
  514 + not returning the expected information. This option changes
  515 + log_ret() to log any errors it sees. With this option disabled,
  516 + log_ret() is a nop.
  517 +
  518 + You can add log_ret() to all functions which return an error code.
  519 +
507 520 endmenu
508 521  
509 522 config DEFAULT_FDT_FILE
configs/sandbox_defconfig
... ... @@ -18,6 +18,7 @@
18 18 CONFIG_PRE_CON_BUF_ADDR=0x100000
19 19 CONFIG_LOG=y
20 20 CONFIG_LOG_MAX_LEVEL=6
  21 +CONFIG_LOG_ERROR_RETURN=y
21 22 CONFIG_CMD_CPU=y
22 23 CONFIG_CMD_LICENSE=y
23 24 CONFIG_CMD_BOOTZ=y
... ... @@ -148,6 +148,14 @@
148 148 as the category, so you should #define this right at the top of the source
149 149 file to ensure the category is correct.
150 150  
  151 +You can also define CONFIG_LOG_ERROR_RETURN to enable the log_ret() macro. This
  152 +can be used whenever your function returns an error value:
  153 +
  154 + return log_ret(uclass_first_device(UCLASS_MMC, &dev));
  155 +
  156 +This will write a log record when an error code is detected (a value < 0). This
  157 +can make it easier to trace errors that are generated deep in the call stack.
  158 +
151 159  
152 160 Code size
153 161 ---------
... ... @@ -159,6 +159,17 @@
159 159 ({ if (!(x) && _DEBUG) \
160 160 __assert_fail(#x, __FILE__, __LINE__, __func__); })
161 161  
  162 +#ifdef CONFIG_LOG_ERROR_RETURN
  163 +#define log_ret(_ret) ({ \
  164 + int __ret = (_ret); \
  165 + if (__ret < 0) \
  166 + log(LOG_CATEGORY, LOGL_ERR, "returning err=%d\n", __ret); \
  167 + __ret; \
  168 + })
  169 +#else
  170 +#define log_ret(_ret) (_ret)
  171 +#endif
  172 +
162 173 /**
163 174 * struct log_rec - a single log record
164 175 *