Improved allocation failure reporting

Now it reports file and line number of the function too.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2018-12-20 14:13:14 +00:00
parent 6f0daf8076
commit 1ea611c90e
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
4 changed files with 59 additions and 9 deletions

View File

@ -4,7 +4,7 @@ deps = [
dependency('xcb', version: '>=1.9.2'), dependency('xcb', version: '>=1.9.2'),
] ]
srcs = [ files('compton.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', srcs = [ files('compton.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', 'utils.c',
'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c')] 'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c')]
cflags = [] cflags = []

View File

@ -11,6 +11,25 @@ char *
mstrjoin3(const char *src1, const char *src2, const char *src3); mstrjoin3(const char *src1, const char *src2, const char *src3);
void mstrextend(char **psrc1, const char *src2); void mstrextend(char **psrc1, const char *src2);
static inline int uitostr(unsigned int n, char *buf) {
int ret = 0;
unsigned int tmp = n;
while (tmp > 0) {
tmp /= 10;
ret++;
}
if (ret == 0)
ret = 1;
int pos = ret;
while (pos--) {
buf[pos] = n%10 + '0';
n /= 10;
}
return ret;
}
static inline const char * static inline const char *
skip_space_const(const char *src) { skip_space_const(const char *src) {
if (!src) if (!src)

34
src/utils.c Normal file
View File

@ -0,0 +1,34 @@
#include <stdio.h>
#include <sys/uio.h>
#include "compiler.h"
#include "string_utils.h"
#include "utils.h"
/// Report allocation failure without allocating memory
void report_allocation_failure(const char *func, const char *file, unsigned int line) {
// Since memory allocation failed, we try to print this error message without any
// memory allocation. Since logging framework allocates memory (and might even
// have not been initialized yet), so we can't use it.
char buf[11];
int llen = uitostr(line, buf);
const char msg1[] = " has failed to allocate memory, ";
const char msg2[] = ". Aborting...\n";
const struct iovec v[] = {
{.iov_base = (void *)func, .iov_len = strlen(func)},
{.iov_base = "()", .iov_len = 2},
{.iov_base = (void *)msg1, .iov_len = sizeof(msg1) - 1},
{.iov_base = "at ", .iov_len = 3},
{.iov_base = (void *)file, .iov_len = strlen(file)},
{.iov_base = ":", .iov_len = 1},
{.iov_base = buf, .iov_len = llen},
{.iov_base = (void *)msg2, .iov_len = sizeof(msg2) - 1},
};
writev(STDERR_FILENO, v, ARR_SIZE(v));
abort();
unreachable;
}
// vim: set noet sw=8 ts=8 :

View File

@ -101,24 +101,21 @@ normalize_d(double d) {
return normalize_d_range(d, 0.0, 1.0); return normalize_d_range(d, 0.0, 1.0);
} }
void report_allocation_failure(const char *func, const char *file, unsigned int line);
/** /**
* @brief Quit if the passed-in pointer is empty. * @brief Quit if the passed-in pointer is empty.
*/ */
static inline void * static inline void *
allocchk_(const char *func_name, void *ptr) { allocchk_(const char *func_name, const char *file, unsigned int line, void *ptr) {
if (unlikely(!ptr)) { if (unlikely(!ptr)) {
// Since memory allocation failed, we try to print report_allocation_failure(func_name, file, line);
// this error message without any memory allocation.
const char msg[] = "(): Failed to allocate memory\n";
write(STDERR_FILENO, func_name, strlen(func_name));
write(STDERR_FILENO, msg, ARR_SIZE(msg));
abort();
} }
return ptr; return ptr;
} }
/// @brief Wrapper of allocchk_(). /// @brief Wrapper of allocchk_().
#define allocchk(ptr) allocchk_(__func__, ptr) #define allocchk(ptr) allocchk_(__func__, __FILE__, __LINE__, ptr)
/// @brief Wrapper of malloc(). /// @brief Wrapper of malloc().
#define cmalloc(type) ((type *) allocchk(malloc(sizeof(type)))) #define cmalloc(type) ((type *) allocchk(malloc(sizeof(type))))