Skip to content

Commit

Permalink
Merge pull request #1 from daddinuz/0.4.0
Browse files Browse the repository at this point in the history
0.4.0
  • Loading branch information
daddinuz authored Jun 12, 2018
2 parents bafcad4 + d9e00a1 commit 87236a6
Show file tree
Hide file tree
Showing 18 changed files with 793 additions and 852 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ bin/*
lib/*
build/
coverage/
cmake-build-debug/
cmake-build-*/

# IDEs and editors
*.idea
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
cmake_minimum_required(VERSION 3.8)
project(watchdog C)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror")

# dependencies
include_directories(deps)
include(deps/error/build.cmake)
include(deps/panic/build.cmake)
include(deps/process/build.cmake)

# archive
include_directories(sources)
Expand Down
35 changes: 19 additions & 16 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
The MIT License (MIT)

Copyright (c) 2016-Present Davide Di Carlo
Copyright (c) 2018 Davide Di Carlo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
112 changes: 19 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,32 @@
Watchdog
=========

Watchdog is a C99-compliant runtime memory tracer library useful to find memory leaks or analyze memory usage of a
specific module or even an entire application.
Basically Watchdog creates a layer over the C stdlib.h routines used to manage memory such as 'malloc'/'free' in order
to maintain the whole "history" of your dynamic allocated variables with a small overhead over performances and memory.
This feature may come in handy in development stage, during a memory leak hunting session, while analyzing the memory
bottle-neck of you program.
Watchdog is a C99-compliant runtime dynamically-allocated memory-tracer library that may come in handy at the
development stage, during a memory leak hunting session, or while analyzing the memory bottle-neck of you program.

### Integrate into your code
### How does it work?

Watchdog is designed to be really simple to integrate into your existing code, basically you just have to include
"watchdog.h" instead of "stdlib.h", if NDEBUG is defined watchdog is automatically disabled, so that programs will run
with zero overhead using the standard C library allocators in "stdlib.h".
Watchdog fulfills only the following task:

Is strongly recommend to use Watchdog only in pre-production stages.
* log every usage of heap memory while the program is running.

### Dump memory while running
This allows, with a small overhead over performances, to maintain the whole "history" of the dynamic memory usage, that can be analyzed in a separate stage.
At this point one can freely analyze the "history" by itself. Alternatively [watchdog analyzer](https://github.com/daddinuz/watchdog_analyzer "watchdog_analyzer") can be used to ease this task.

Watchdog will automatically register a signal handler used to dump the memory usage report while the application is running.
### How to integrate?

### Report
Watchdog is designed to be integrated simply into the existing code. One should just include "watchdog.h" instead of "stdlib.h" into the files that need to be traced.

By now the only supported output formats are JSON and YAML,
below there is a memory report of the example program under the `examples/` folder using YAML format:
Watchdog does not trace external libraries. It only traces those ones in which it is included.

```bash
$ ./cmake-build-debug/main
"0x521ca90":
status: in use
chunks:
- href: /watchdog/examples/main.c:42
file: /watchdog/examples/main.c
line: 42
size: 30
call: realloc
- href: /watchdog/examples/main.c:42
file: /watchdog/examples/main.c
line: 42
size: 28
call: realloc
- href: /watchdog/examples/main.c:42
file: /watchdog/examples/main.c
line: 42
size: 26
call: realloc
- href: /watchdog/examples/main.c:42
file: /watchdog/examples/main.c
line: 42
size: 24
call: realloc
- href: /watchdog/examples/main.c:42
file: /watchdog/examples/main.c
line: 42
size: 22
call: realloc
- href: /watchdog/examples/main.c:42
file: /watchdog/examples/main.c
line: 42
size: 20
call: realloc
- href: /watchdog/examples/main.c:42
file: /watchdog/examples/main.c
line: 42
size: 18
call: realloc
- href: /watchdog/examples/main.c:42
file: /watchdog/examples/main.c
line: 42
size: 16
call: realloc
- href: /watchdog/examples/main.c:40
file: /watchdog/examples/main.c
line: 40
size: 5
call: realloc
### How to turn it off?

If NDEBUG is defined, watchdog is automatically disabled so that programs will run with zero overhead,
using the standard allocators in "stdlib.h".

"0x521c260":
status: released
chunks:
- href: /watchdog/examples/main.c:38
file: /watchdog/examples/main.c
line: 38
size: 0
call: free
- href: /watchdog/examples/main.c:37
file: /watchdog/examples/main.c
line: 37
size: 48
call: realloc
- href: /watchdog/examples/main.c:36
file: /watchdog/examples/main.c
line: 36
size: 10
call: calloc
### Recommendations

"0x521c060":
status: in use
chunks:
- href: /watchdog/examples/main.c:33
file: /watchdog/examples/main.c
line: 33
size: 8
call: malloc
```
It is strongly recommended to use Watchdog only in pre-production stages.

Useful links:
* [Analyzer and TUI viewer](https://github.com/daddinuz/watchdog "watchdog") for watchdog reports.
6 changes: 6 additions & 0 deletions deps/error/build.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(ARCHIVE_NAME error)
message("${ARCHIVE_NAME}@${CMAKE_CURRENT_LIST_DIR} using: ${CMAKE_CURRENT_LIST_FILE}")

file(GLOB ARCHIVE_HEADERS ${CMAKE_CURRENT_LIST_DIR}/*.h)
file(GLOB ARCHIVE_SOURCES ${CMAKE_CURRENT_LIST_DIR}/*.c)
add_library(${ARCHIVE_NAME} ${ARCHIVE_HEADERS} ${ARCHIVE_SOURCES})
38 changes: 38 additions & 0 deletions deps/error/error.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Author: daddinuz
* email: [email protected]
*
* Copyright (c) 2018 Davide Di Carlo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

#include <assert.h>
#include "error.h"

const char *Error_explain(Error self) {
assert(self);
return self->__message;
}

const Error Ok = Error_new("Ok");
const Error OutOfMemory = Error_new("Out of memory");
98 changes: 98 additions & 0 deletions deps/error/error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Author: daddinuz
* email: [email protected]
*
* Copyright (c) 2018 Davide Di Carlo
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#if !(defined(__GNUC__) || defined(__clang__))
#define __attribute__(...)
#endif

#define ERROR_VERSION_MAJOR 0
#define ERROR_VERSION_MINOR 2
#define ERROR_VERSION_PATCH 0
#define ERROR_VERSION_SUFFIX ""
#define ERROR_VERSION_IS_RELEASE 0
#define ERROR_VERSION_HEX 0x000200

/**
* Represents errors that may occur at runtime.
* Every error instance must be a singleton, in order to check if two errors are equal a simple comparison
* between pointers can be done.
*
* @attention
* This type must be treated as opaque therefore its members should never be accessed directly.
*/
typedef struct __Error {
const char *__message;
} const *Error;

/**
* An helper macro used for type hinting, useful when writing interfaces.
* By convention the annotations are the errors that may be returned.
*/
#define ErrorOf(...) \
Error

/**
* Helper macro to create new singleton errors.
* This macro should be used only to define new global errors, and Errors defined with this macro must be declared const:
*
* @code
* const Error OutOfMemoryError = Error_new("Out of memory");
* @endcode
*/
#define Error_new(xMessage) \
((Error) &((const struct __Error) {.__message=(xMessage)}))

/**
* Gets the error message explanation.
*
* @param self The error instance <b>must not be NULL</b>.
* @return The error message.
*/
extern const char *
Error_explain(Error self)
__attribute__((__warn_unused_result__, __nonnull__));

/**
* The Ok Error instance to notify a successful execution.
*/
extern const Error Ok;

/**
* Some error instances
*/
extern const Error OutOfMemory;

#ifdef __cplusplus
}
#endif
16 changes: 16 additions & 0 deletions deps/error/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "error",
"repo": "daddinuz/error",
"version": "0.2.0",
"license": "MIT",
"description": "Error representation.",
"keywords": [
"Error Handling",
"Error"
],
"src": [
"sources/error.h",
"sources/error.c"
],
"makefile": "sources/build.cmake"
}
7 changes: 7 additions & 0 deletions deps/process/build.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
set(ARCHIVE_NAME process)
message("${ARCHIVE_NAME}@${CMAKE_CURRENT_LIST_DIR} using: ${CMAKE_CURRENT_LIST_FILE}")

file(GLOB ARCHIVE_HEADERS ${CMAKE_CURRENT_LIST_DIR}/*.h)
file(GLOB ARCHIVE_SOURCES ${CMAKE_CURRENT_LIST_DIR}/*.c)
add_library(${ARCHIVE_NAME} ${ARCHIVE_HEADERS} ${ARCHIVE_SOURCES})
target_link_libraries(${ARCHIVE_NAME} PRIVATE error panic)
18 changes: 18 additions & 0 deletions deps/process/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "process",
"repo": "daddinuz/process",
"version": "0.1.0",
"license": "MIT",
"description": "...",
"keywords": [
],
"src": [
"sources/process.h",
"sources/process.c"
],
"dependencies": {
"daddinuz/error": "0.2.0",
"daddinuz/panic": "0.3.0"
},
"makefile": "sources/build.cmake"
}
Loading

0 comments on commit 87236a6

Please sign in to comment.