You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2019/12/03 22:49:33 UTC
[qpid-proton] 02/02: PROTON-2144: Instrument all memory
allocation/deallocation in proton core - Replace all use of
malloc/calloc/realloc/free in libqpid-proton-core with instrumented memory
tracking calls
This is an automated email from the ASF dual-hosted git repository.
astitcher pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
commit 927d43f43118b9f1558bf721ac7a3a97b9fd7c7c
Author: Andrew Stitcher <as...@apache.org>
AuthorDate: Fri Nov 22 15:12:04 2019 -0500
PROTON-2144: Instrument all memory allocation/deallocation in proton core
- Replace all use of malloc/calloc/realloc/free in libqpid-proton-core with
instrumented memory tracking calls
---
c/include/proton/cid.h | 5 +++--
c/src/core/buffer.c | 19 ++++++++++++-------
c/src/core/codec.c | 9 +++++----
c/src/core/engine.c | 16 +++++++++-------
c/src/core/error.c | 15 ++++++++++-----
c/src/core/object/iterator.c | 7 +++++--
c/src/core/object/list.c | 11 +++++++----
c/src/core/object/map.c | 11 +++++++----
c/src/core/object/object.c | 11 +++++++----
c/src/core/object/record.c | 9 ++++++---
c/src/core/object/string.c | 10 ++++++----
c/src/core/transport.c | 23 ++++++++++++-----------
c/src/core/util.c | 12 ++++++++----
c/src/core/util.h | 2 ++
c/tests/fuzz/CMakeLists.txt | 2 +-
15 files changed, 100 insertions(+), 62 deletions(-)
diff --git a/c/include/proton/cid.h b/c/include/proton/cid.h
index c416331..d35c8ac 100644
--- a/c/include/proton/cid.h
+++ b/c/include/proton/cid.h
@@ -40,8 +40,8 @@ typedef enum {
CID_pn_collector,
CID_pn_event,
- CID_pn_encoder, /* Unused */
- CID_pn_decoder, /* Unused */
+ CID_pn_buffer,
+ CID_pn_error,
CID_pn_data,
CID_pn_connection,
@@ -62,6 +62,7 @@ typedef enum {
CID_pn_selectable,
CID_pn_url,
+ CID_pn_strdup,
CID_pn_listener,
CID_pn_proactor,
diff --git a/c/src/core/buffer.c b/c/src/core/buffer.c
index e990581..f571e26 100644
--- a/c/src/core/buffer.c
+++ b/c/src/core/buffer.c
@@ -20,14 +20,17 @@
*/
#include <proton/error.h>
+#include <proton/object.h>
+
#ifndef __cplusplus
#include <stdbool.h>
#endif
-#include <stdlib.h>
+#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "buffer.h"
+#include "memory.h"
#include "util.h"
struct pn_buffer_t {
@@ -37,17 +40,19 @@ struct pn_buffer_t {
char *bytes;
};
+PN_STRUCT_CLASSDEF(pn_buffer)
+
pn_buffer_t *pn_buffer(size_t capacity)
{
- pn_buffer_t *buf = (pn_buffer_t *) malloc(sizeof(pn_buffer_t));
+ pn_buffer_t *buf = (pn_buffer_t *) pni_mem_allocate(PN_CLASSCLASS(pn_buffer), sizeof(pn_buffer_t));
if (buf != NULL) {
buf->capacity = capacity;
buf->start = 0;
buf->size = 0;
if (capacity > 0) {
- buf->bytes = (char *)malloc(capacity);
+ buf->bytes = (char *) pni_mem_suballocate(PN_CLASSCLASS(pn_buffer), buf, capacity);
if (buf->bytes == NULL) {
- free(buf);
+ pni_mem_deallocate(PN_CLASSCLASS(pn_buffer), buf);
buf = NULL;
}
}
@@ -61,8 +66,8 @@ pn_buffer_t *pn_buffer(size_t capacity)
void pn_buffer_free(pn_buffer_t *buf)
{
if (buf) {
- free(buf->bytes);
- free(buf);
+ pni_mem_subdeallocate(PN_CLASSCLASS(pn_buffer), buf, buf->bytes);
+ pni_mem_deallocate(PN_CLASSCLASS(pn_buffer), buf);
}
}
@@ -146,7 +151,7 @@ int pn_buffer_ensure(pn_buffer_t *buf, size_t size)
}
if (buf->capacity != old_capacity) {
- char* new_bytes = (char *)realloc(buf->bytes, buf->capacity);
+ char* new_bytes = (char *) pni_mem_subreallocate(PN_CLASSCLASS(pn_buffer), buf, buf->bytes, buf->capacity);
if (new_bytes) {
buf->bytes = new_bytes;
diff --git a/c/src/core/codec.c b/c/src/core/codec.c
index e26ef81..b50f286 100644
--- a/c/src/core/codec.c
+++ b/c/src/core/codec.c
@@ -26,7 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
-#include <stdlib.h>
+#include <stddef.h>
#include <ctype.h>
#include "encodings.h"
#define DEFINE_FIELDS
@@ -37,6 +37,7 @@
#include "encoder.h"
#include "data.h"
#include "logger_private.h"
+#include "memory.h"
const char *pn_type_name(pn_type_t type)
{
@@ -84,7 +85,7 @@ static inline void pni_atom_init(pn_atom_t *atom, pn_type_t type)
static void pn_data_finalize(void *object)
{
pn_data_t *data = (pn_data_t *) object;
- free(data->nodes);
+ pni_mem_subdeallocate(pn_class(data), data, data->nodes);
pn_buffer_free(data->buf);
pn_error_free(data->error);
}
@@ -375,7 +376,7 @@ pn_data_t *pn_data(size_t capacity)
pn_data_t *data = (pn_data_t *) pn_class_new(&clazz, sizeof(pn_data_t));
data->capacity = capacity;
data->size = 0;
- data->nodes = capacity ? (pni_node_t *) malloc(capacity * sizeof(pni_node_t)) : NULL;
+ data->nodes = capacity ? (pni_node_t *) pni_mem_suballocate(&clazz, data, capacity * sizeof(pni_node_t)) : NULL;
data->buf = NULL;
data->parent = 0;
data->current = 0;
@@ -424,7 +425,7 @@ static int pni_data_grow(pn_data_t *data)
else if (capacity < PNI_NID_MAX/2) capacity *= 2;
else capacity = PNI_NID_MAX;
- pni_node_t *new_nodes = (pni_node_t *)realloc(data->nodes, capacity * sizeof(pni_node_t));
+ pni_node_t *new_nodes = (pni_node_t *) pni_mem_subreallocate(pn_class(data), data, data->nodes, capacity * sizeof(pni_node_t));
if (new_nodes == NULL) return PN_OUT_OF_MEMORY;
data->capacity = capacity;
data->nodes = new_nodes;
diff --git a/c/src/core/engine.c b/c/src/core/engine.c
index f2e3072..4187cad 100644
--- a/c/src/core/engine.c
+++ b/c/src/core/engine.c
@@ -20,18 +20,20 @@
*/
#include "engine-internal.h"
+
#include "framing.h"
-#include <stdlib.h>
-#include <string.h>
+#include "memory.h"
+#include "platform/platform.h"
+#include "platform/platform_fmt.h"
#include "protocol.h"
+#include "transport.h"
#include <assert.h>
#include <stdarg.h>
+#include <stddef.h>
#include <stdio.h>
+#include <string.h>
-#include "platform/platform.h"
-#include "platform/platform_fmt.h"
-#include "transport.h"
static void pni_session_bound(pn_session_t *ssn);
static void pni_link_bound(pn_link_t *link);
@@ -209,7 +211,7 @@ void pn_condition_init(pn_condition_t *condition)
}
pn_condition_t *pn_condition() {
- pn_condition_t *c = (pn_condition_t*)malloc(sizeof(pn_condition_t));
+ pn_condition_t *c = (pn_condition_t*)pni_mem_allocate(PN_VOID, sizeof(pn_condition_t));
pn_condition_init(c);
return c;
}
@@ -225,7 +227,7 @@ void pn_condition_free(pn_condition_t *c) {
if (c) {
pn_condition_clear(c);
pn_condition_tini(c);
- free(c);
+ pni_mem_deallocate(PN_VOID, c);
}
}
diff --git a/c/src/core/error.c b/c/src/core/error.c
index 5799b00..d533a21 100644
--- a/c/src/core/error.c
+++ b/c/src/core/error.c
@@ -19,11 +19,14 @@
*
*/
+#include <proton/error.h>
+#include <proton/object.h>
+
+#include "memory.h"
#include "platform/platform.h"
#include "util.h"
#include <proton/connection.h>
-#include <proton/error.h>
#include <proton/link.h>
#include <proton/session.h>
@@ -36,9 +39,11 @@ struct pn_error_t {
int code;
};
+PN_STRUCT_CLASSDEF(pn_error)
+
pn_error_t *pn_error()
{
- pn_error_t *error = (pn_error_t *) malloc(sizeof(pn_error_t));
+ pn_error_t *error = (pn_error_t *) pni_mem_allocate(PN_CLASSCLASS(pn_error), sizeof(pn_error_t));
if (error != NULL) {
error->code = 0;
error->text = NULL;
@@ -49,8 +54,8 @@ pn_error_t *pn_error()
void pn_error_free(pn_error_t *error)
{
if (error) {
- free(error->text);
- free(error);
+ pni_mem_subdeallocate(PN_CLASSCLASS(pn_error), error, error->text);
+ pni_mem_deallocate(PN_CLASSCLASS(pn_error), error);
}
}
@@ -58,7 +63,7 @@ void pn_error_clear(pn_error_t *error)
{
if (error) {
error->code = 0;
- free(error->text);
+ pni_mem_subdeallocate(PN_CLASSCLASS(pn_error), error, error->text);
error->text = NULL;
}
}
diff --git a/c/src/core/object/iterator.c b/c/src/core/object/iterator.c
index 61b3b8e..a80ac9a 100644
--- a/c/src/core/object/iterator.c
+++ b/c/src/core/object/iterator.c
@@ -20,6 +20,9 @@
*/
#include <proton/object.h>
+
+#include "core/memory.h"
+
#include <stdlib.h>
#include <assert.h>
@@ -40,7 +43,7 @@ static void pn_iterator_initialize(void *object)
static void pn_iterator_finalize(void *object)
{
pn_iterator_t *it = (pn_iterator_t *) object;
- free(it->state);
+ pni_mem_subdeallocate(pn_class(object), object, it->state);
}
#define CID_pn_iterator CID_pn_object
@@ -61,7 +64,7 @@ void *pn_iterator_start(pn_iterator_t *iterator, pn_iterator_next_t next,
assert(next);
iterator->next = next;
if (iterator->size < size) {
- iterator->state = realloc(iterator->state, size);
+ iterator->state = pni_mem_subreallocate(pn_class(iterator), iterator, iterator->state, size);
}
return iterator->state;
}
diff --git a/c/src/core/object/list.c b/c/src/core/object/list.c
index 76c70d2..3d2bc0f 100644
--- a/c/src/core/object/list.c
+++ b/c/src/core/object/list.c
@@ -20,7 +20,10 @@
*/
#include <proton/object.h>
-#include <stdlib.h>
+
+#include "core/memory.h"
+
+#include <stddef.h>
#include <assert.h>
struct pn_list_t {
@@ -57,7 +60,7 @@ static void pni_list_ensure(pn_list_t *list, size_t capacity)
if (list->capacity < capacity) {
size_t newcap = list->capacity;
while (newcap < capacity) { newcap *= 2; }
- list->elements = (void **) realloc(list->elements, newcap * sizeof(void *));
+ list->elements = (void **) pni_mem_subreallocate(pn_class(list), list, list->elements, newcap * sizeof(void *));
assert(list->elements);
list->capacity = newcap;
}
@@ -197,7 +200,7 @@ static void pn_list_finalize(void *object)
for (size_t i = 0; i < list->size; i++) {
pn_class_decref(list->clazz, pn_list_get(list, i));
}
- free(list->elements);
+ pni_mem_subdeallocate(pn_class(list), list, list->elements);
}
static uintptr_t pn_list_hashcode(void *object)
@@ -260,7 +263,7 @@ pn_list_t *pn_list(const pn_class_t *clazz, size_t capacity)
pn_list_t *list = (pn_list_t *) pn_class_new(&list_clazz, sizeof(pn_list_t));
list->clazz = clazz;
list->capacity = capacity ? capacity : 16;
- list->elements = (void **) malloc(list->capacity * sizeof(void *));
+ list->elements = (void **) pni_mem_suballocate(&list_clazz, list, list->capacity * sizeof(void *));
list->size = 0;
return list;
}
diff --git a/c/src/core/object/map.c b/c/src/core/object/map.c
index cd38f19..ee306ac 100644
--- a/c/src/core/object/map.c
+++ b/c/src/core/object/map.c
@@ -20,7 +20,10 @@
*/
#include <proton/object.h>
-#include <stdlib.h>
+
+#include "core/memory.h"
+
+#include <stddef.h>
#include <assert.h>
#define PNI_ENTRY_FREE (0)
@@ -57,7 +60,7 @@ static void pn_map_finalize(void *object)
}
}
- free(map->entries);
+ pni_mem_subdeallocate(pn_class(map), map, map->entries);
}
static uintptr_t pn_map_hashcode(void *object)
@@ -79,7 +82,7 @@ static uintptr_t pn_map_hashcode(void *object)
static void pni_map_allocate(pn_map_t *map)
{
- map->entries = (pni_entry_t *) malloc(map->capacity * sizeof (pni_entry_t));
+ map->entries = (pni_entry_t *) pni_mem_suballocate(pn_class(map), map, map->capacity * sizeof (pni_entry_t));
if (map->entries != NULL) {
for (size_t i = 0; i < map->capacity; i++) {
map->entries[i].key = NULL;
@@ -183,7 +186,7 @@ static bool pni_map_ensure(pn_map_t *map, size_t capacity)
}
}
- free(entries);
+ pni_mem_subdeallocate(pn_class(map), map, entries);
return true;
}
diff --git a/c/src/core/object/object.c b/c/src/core/object/object.c
index a6952b6..794a032 100644
--- a/c/src/core/object/object.c
+++ b/c/src/core/object/object.c
@@ -20,6 +20,9 @@
*/
#include <proton/object.h>
+
+#include "core/memory.h"
+
#include <stdlib.h>
#include <assert.h>
@@ -32,12 +35,12 @@ intptr_t pn_object_compare(void *a, void *b) { return (intptr_t) a - (intptr_t)
const pn_class_t PN_OBJECT[] = {PN_CLASS(pn_object)};
#define pn_void_initialize NULL
-void *pn_void_new(const pn_class_t *clazz, size_t size) { return malloc(size); }
+void *pn_void_new(const pn_class_t *clazz, size_t size) { return pni_mem_allocate(clazz, size); }
void pn_void_incref(void* p) {}
void pn_void_decref(void* p) {}
int pn_void_refcount(void *object) { return -1; }
#define pn_void_finalize NULL
-static void pn_void_free(void *object) { free(object); }
+static void pn_void_free(void *object) { pni_mem_deallocate(PN_VOID, object); }
static const pn_class_t *pn_void_reify(void *object) { return PN_VOID; }
uintptr_t pn_void_hashcode(void *object) { return (uintptr_t) object; }
intptr_t pn_void_compare(void *a, void *b) { return (intptr_t) a - (intptr_t) b; }
@@ -199,7 +202,7 @@ typedef struct {
void *pn_object_new(const pn_class_t *clazz, size_t size)
{
void *object = NULL;
- pni_head_t *head = (pni_head_t *) calloc(1, sizeof(pni_head_t) + size);
+ pni_head_t *head = (pni_head_t *) pni_mem_zallocate(clazz, sizeof(pni_head_t) + size);
if (head != NULL) {
object = head + 1;
head->clazz = clazz;
@@ -240,7 +243,7 @@ void pn_object_decref(void *object)
void pn_object_free(void *object)
{
pni_head_t *head = pni_head(object);
- free(head);
+ pni_mem_deallocate(head->clazz, head);
}
void *pn_incref(void *object)
diff --git a/c/src/core/object/record.c b/c/src/core/object/record.c
index 6f4fe0a..9bde258 100644
--- a/c/src/core/object/record.c
+++ b/c/src/core/object/record.c
@@ -20,7 +20,10 @@
*/
#include <proton/object.h>
-#include <stdlib.h>
+
+#include "core/memory.h"
+
+#include <stddef.h>
#include <assert.h>
typedef struct {
@@ -50,7 +53,7 @@ static void pn_record_finalize(void *object)
pni_field_t *v = &record->fields[i];
pn_class_decref(v->clazz, v->value);
}
- free(record->fields);
+ pni_mem_subdeallocate(pn_class(record), record, record->fields);
}
#define pn_record_hashcode NULL
@@ -78,7 +81,7 @@ static pni_field_t *pni_record_find(pn_record_t *record, pn_handle_t key) {
static pni_field_t *pni_record_create(pn_record_t *record) {
record->size++;
if (record->size > record->capacity) {
- record->fields = (pni_field_t *) realloc(record->fields, record->size * sizeof(pni_field_t));
+ record->fields = (pni_field_t *) pni_mem_subreallocate(pn_class(record), record, record->fields, record->size * sizeof(pni_field_t));
record->capacity = record->size;
}
pni_field_t *field = &record->fields[record->size - 1];
diff --git a/c/src/core/object/string.c b/c/src/core/object/string.c
index 71db6c4..6d429ec 100644
--- a/c/src/core/object/string.c
+++ b/c/src/core/object/string.c
@@ -23,8 +23,10 @@
#include <proton/error.h>
#include <proton/object.h>
+#include "core/memory.h"
+
#include <stdio.h>
-#include <stdlib.h>
+#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <ctype.h>
@@ -40,7 +42,7 @@ struct pn_string_t {
static void pn_string_finalize(void *object)
{
pn_string_t *string = (pn_string_t *) object;
- free(string->bytes);
+ pni_mem_subdeallocate(pn_class(string), string, string->bytes);
}
static uintptr_t pn_string_hashcode(void *object)
@@ -109,7 +111,7 @@ pn_string_t *pn_stringn(const char *bytes, size_t n)
static const pn_class_t clazz = PN_CLASS(pn_string);
pn_string_t *string = (pn_string_t *) pn_class_new(&clazz, sizeof(pn_string_t));
string->capacity = n ? n * sizeof(char) : 16;
- string->bytes = (char *) malloc(string->capacity);
+ string->bytes = (char *) pni_mem_suballocate(&clazz, string, string->capacity);
pn_string_setn(string, bytes, n);
return string;
}
@@ -148,7 +150,7 @@ int pn_string_grow(pn_string_t *string, size_t capacity)
}
if (grow) {
- char *growed = (char *) realloc(string->bytes, string->capacity);
+ char *growed = (char *) pni_mem_subreallocate(pn_class(string), string, string->bytes, string->capacity);
if (growed) {
string->bytes = growed;
} else {
diff --git a/c/src/core/transport.c b/c/src/core/transport.c
index 682a635..7b81dda 100644
--- a/c/src/core/transport.c
+++ b/c/src/core/transport.c
@@ -21,6 +21,7 @@
#include "engine-internal.h"
#include "framing.h"
+#include "memory.h"
#include "platform/platform.h"
#include "platform/platform_fmt.h"
#include "sasl/sasl-internal.h"
@@ -34,7 +35,7 @@
#include "proton/event.h"
-#include <stdlib.h>
+#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
@@ -553,13 +554,13 @@ pn_transport_t *pn_transport(void)
(pn_transport_t *) pn_class_new(&clazz, sizeof(pn_transport_t));
if (!transport) return NULL;
- transport->output_buf = (char *) malloc(transport->output_size);
+ transport->output_buf = (char *) pni_mem_suballocate(&clazz, transport, transport->output_size);
if (!transport->output_buf) {
pn_transport_free(transport);
return NULL;
}
- transport->input_buf = (char *) malloc(transport->input_size);
+ transport->input_buf = (char *) pni_mem_suballocate(&clazz, transport, transport->input_size);
if (!transport->input_buf) {
pn_transport_free(transport);
return NULL;
@@ -649,8 +650,8 @@ static void pn_transport_finalize(void *object)
pn_ssl_free(transport);
pn_sasl_free(transport);
- free(transport->remote_container);
- free(transport->remote_hostname);
+ pni_mem_deallocate(PN_CLASSCLASS(pn_strdup), transport->remote_container);
+ pni_mem_deallocate(PN_CLASSCLASS(pn_strdup), transport->remote_hostname);
pn_free(transport->remote_offered_capabilities);
pn_free(transport->remote_desired_capabilities);
pn_free(transport->remote_properties);
@@ -660,8 +661,8 @@ static void pn_transport_finalize(void *object)
pn_error_free(transport->error);
pn_free(transport->local_channels);
pn_free(transport->remote_channels);
- if (transport->input_buf) free(transport->input_buf);
- if (transport->output_buf) free(transport->output_buf);
+ pni_mem_subdeallocate(pn_class(transport), transport, transport->input_buf);
+ pni_mem_subdeallocate(pn_class(transport), transport, transport->output_buf);
pn_free(transport->scratch);
pn_data_free(transport->args);
pn_data_free(transport->output_args);
@@ -1195,9 +1196,9 @@ int pn_do_open(pn_transport_t *transport, uint8_t frame_type, uint16_t channel,
transport->remote_max_frame = AMQP_MIN_MAX_FRAME_SIZE;
}
}
- free(transport->remote_container);
+ pni_mem_deallocate(PN_CLASSCLASS(pn_strdup), transport->remote_container);
transport->remote_container = container_q ? pn_bytes_strdup(remote_container) : NULL;
- free(transport->remote_hostname);
+ pni_mem_deallocate(PN_CLASSCLASS(pn_strdup), transport->remote_hostname);
transport->remote_hostname = hostname_q ? pn_bytes_strdup(remote_hostname) : NULL;
if (conn) {
@@ -2749,7 +2750,7 @@ static ssize_t transport_produce(pn_transport_t *transport)
else if (transport->remote_max_frame > transport->output_size)
more = pn_min(transport->output_size, transport->remote_max_frame - transport->output_size);
if (more) {
- char *newbuf = (char *)realloc( transport->output_buf, transport->output_size + more );
+ char *newbuf = (char *)pni_mem_subreallocate(pn_class(transport), transport, transport->output_buf, transport->output_size + more );
if (newbuf) {
transport->output_buf = newbuf;
transport->output_size += more;
@@ -2978,7 +2979,7 @@ ssize_t pn_transport_capacity(pn_transport_t *transport) /* <0 == done */
more = pn_min(transport->input_size, transport->local_max_frame - transport->input_size);
}
if (more) {
- char *newbuf = (char *) realloc( transport->input_buf, transport->input_size + more );
+ char *newbuf = (char *) pni_mem_subreallocate(pn_class(transport), transport, transport->input_buf, transport->input_size + more );
if (newbuf) {
transport->input_buf = newbuf;
transport->input_size += more;
diff --git a/c/src/core/util.c b/c/src/core/util.c
index 2aa3076..18a9464 100644
--- a/c/src/core/util.c
+++ b/c/src/core/util.c
@@ -19,16 +19,18 @@
*
*/
-#include "buffer.h"
#include "util.h"
+#include "buffer.h"
+#include "memory.h"
+
#include <proton/error.h>
#include <proton/types.h>
#include <proton/type_compat.h>
#include <stdarg.h>
#include <stdio.h>
-#include <stdlib.h>
+#include <stddef.h>
#include <ctype.h>
#include <string.h>
@@ -112,10 +114,12 @@ bool pn_env_bool(const char *name)
!pn_strcasecmp(v, "yes") || !pn_strcasecmp(v, "on"));
}
+PN_STRUCT_CLASSDEF(pn_strdup)
+
char *pn_strdup(const char *src)
{
if (!src) return NULL;
- char *dest = (char *) malloc(strlen(src)+1);
+ char *dest = (char *) pni_mem_allocate(PN_CLASSCLASS(pn_strdup), strlen(src)+1);
if (!dest) return NULL;
return strcpy(dest, src);
}
@@ -128,7 +132,7 @@ char *pn_strndup(const char *src, size_t n)
size++;
}
- char *dest = (char *) malloc(size + 1);
+ char *dest = (char *) pni_mem_allocate(PN_CLASSCLASS(pn_strdup), size + 1);
if (!dest) return NULL;
strncpy(dest, src, pn_min(n, size));
dest[size] = '\0';
diff --git a/c/src/core/util.h b/c/src/core/util.h
index efa9d6f..9ae62ea 100644
--- a/c/src/core/util.h
+++ b/c/src/core/util.h
@@ -39,8 +39,10 @@ int pn_quote(pn_string_t *dst, const char *src, size_t size);
bool pn_env_bool(const char *name);
pn_timestamp_t pn_timestamp_min(pn_timestamp_t a, pn_timestamp_t b);
+extern const pn_class_t PN_CLASSCLASS(pn_strdup)[];
char *pn_strdup(const char *src);
char *pn_strndup(const char *src, size_t n);
+
int pn_strcasecmp(const char* a, const char* b);
int pn_strncasecmp(const char* a, const char* b, size_t len);
diff --git a/c/tests/fuzz/CMakeLists.txt b/c/tests/fuzz/CMakeLists.txt
index 85703f3..070b691 100644
--- a/c/tests/fuzz/CMakeLists.txt
+++ b/c/tests/fuzz/CMakeLists.txt
@@ -56,7 +56,7 @@ pn_add_fuzz_test (fuzz-connection-driver fuzz-connection-driver.c)
pn_add_fuzz_test (fuzz-message-decode fuzz-message-decode.c)
# pn_url_parse is not in proton core and is only used by messenger so compile specially
-pn_add_fuzz_test (fuzz-url fuzz-url.c ${PN_C_SOURCE_DIR}/extra/url.c ${PN_C_SOURCE_DIR}/core/util.c)
+pn_add_fuzz_test (fuzz-url fuzz-url.c ${PN_C_SOURCE_DIR}/extra/url.c ${PN_C_SOURCE_DIR}/core/util.c ${PN_C_SOURCE_DIR}/core/memory.c)
target_compile_definitions(fuzz-url PRIVATE PROTON_DECLARE_STATIC)
# This regression test can take a very long time so don't run by default
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org