Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ shared_library("zoslib") {
"include/zos-sys-info.h",
"include/zos-tls.h",
"src/zos.cc",
"src/zos-allocs-trace.cc",
"src/zos-bpx.cc",
"src/zos-char-util.cc",
"src/zos-getentropy.cc",
Expand All @@ -45,6 +46,7 @@ shared_library("zoslib") {
"src/zos-spawn.cc",
"src/zos-sys-info.cc",
"src/zos-tls.cc",
"src/zos-tsearch.c",
]

configs += [ ":zoslib_config" ]
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ project(libzoslib CXX C ASM)

if(${CMAKE_C_COMPILER} MATCHES xlclang)
include_directories(BEFORE include)
include_directories(BEFORE include include/c++)
else()
include_directories(BEFORE include include/c++/v1)
endif()
Expand Down
27 changes: 27 additions & 0 deletions include/c++/cstdlib
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
///////////////////////////////////////////////////////////////////////////////
// Licensed Materials - Property of IBM
// ZOSLIB
// (C) Copyright IBM Corp. 2024. All Rights Reserved.
// US Government Users Restricted Rights - Use, duplication
// or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
///////////////////////////////////////////////////////////////////////////////

#pragma once
/*
* Works around error with xlclang:
* <compiler-path>/c++/cstdlib:line:col: error: no member named '__calloc_prtsrc' in the global namespace
* <zoslib-path>/include/stdlib.h:line:col: note: expanded from macro 'calloc'
* #define calloc __calloc_prtsrc
* Same for malloc and realloc.
*/

#if defined(ZOSLIB_TRACE_ALLOCS) && defined(__clang__) && defined(__ibmxl__)
#undef __calloc_prtsrc
#undef __malloc_prtsrc
#undef __realloc_prtsrc
void *__calloc_prtsrc(size_t, size_t);
void *__malloc_prtsrc(size_t);
void *__realloc_prtsrc(void *, size_t);
#endif

#include_next <cstdlib>
65 changes: 65 additions & 0 deletions include/stdlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,50 @@ __Z_EXPORT int __mkstemp_ascii(char*);
#define getenv __getenv_replaced
#endif

#ifdef ZOSLIB_TRACE_ALLOCS

#include <sys/types.h>

#if defined(__cplusplus)
extern "C" {
#endif

void *__calloc_orig(size_t, size_t) __asm("calloc");
void *__malloc_orig(size_t) __asm("malloc");
void *__realloc_orig(void *, size_t) __asm("realloc");
void __free_orig(void *) __asm("free");
void *__malloc31_orig(size_t) __asm("__malloc31");

__Z_EXPORT void * __calloc_trace(size_t, size_t, const char *pfname, int linenum);
__Z_EXPORT void * __malloc_trace(size_t, const char *pfname, int linenum);
__Z_EXPORT void * __realloc_trace(void *, size_t, const char *pfname, int linenum);
__Z_EXPORT void * __reallocf_trace(void *, size_t, const char *pfname, int linenum);
__Z_EXPORT void __free_trace(void *);
__Z_EXPORT void * __malloc31_trace(size_t, const char *pfname, int linenum);

#define __calloc_prtsrc(x, y) __calloc_trace(x, y, __FILE__, __LINE__)
#define __malloc_prtsrc(x) __malloc_trace(x, __FILE__, __LINE__)
#define __realloc_prtsrc(x, y) __realloc_trace(x, y, __FILE__, __LINE__)
#define __reallocf_prtsrc(x, y) __reallocf_trace(x, y, __FILE__, __LINE__)
#define __malloc31_prtsrc(x) __malloc31_trace(x, __FILE__, __LINE__)

#if defined(__cplusplus)
}
#endif

#undef calloc
#undef malloc
#undef realloc
#undef free
#undef __malloc31

#define calloc __calloc_replaced
#define malloc __malloc_replaced
#define realloc __realloc_replaced
#define free __free_replaced
#define __malloc31 __malloc31_replaced

#endif /* ZOSLIB_TRACE_ALLOCS */

#include_next <stdlib.h>

Expand Down Expand Up @@ -83,6 +127,27 @@ __Z_EXPORT char* getenv(const char*) __asm("@@A00423");
#endif
#endif

#ifdef ZOSLIB_TRACE_ALLOCS
#undef calloc
#undef malloc
#undef realloc
#undef free
#undef __malloc31

#define calloc __calloc_prtsrc
#define malloc __malloc_prtsrc
#define realloc __realloc_prtsrc
#define __malloc31 __malloc31_prtsrc
// #define free __free_prtsrc
// fails with clang:
// .../include/c++/v1/locale:283:68: error: reference to unresolved using
// declaration
// unique_ptr<unsigned char, void(*)(void*)> __stat_hold(nullptr, free);

void free(void *) __asm("__free_trace");

#endif /* ZOSLIB_TRACE_ALLOCS */

#if defined(__cplusplus)
extern "C" {
#endif
Expand Down
36 changes: 36 additions & 0 deletions include/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,51 @@

#include "zos-macros.h"

#if defined(ZOSLIB_TRACE_ALLOCS)
#include <sys/types.h>

#if defined(__cplusplus)
extern "C" {
#endif

char *__strdup_orig(const char *) __asm("strdup");

__Z_EXPORT char * __strdup_trace(const char *, const char *pfname, int linenum);
__Z_EXPORT char * __strndup_trace(const char *, size_t n, const char *pfname, int linenum);

#if defined(__cplusplus)
}
#endif

#define __strdup_prtsrc(x) __strdup_trace(x, __FILE__, __LINE__)
#define __strndup_prtsrc(x,n) __strndup_trace(x, n, __FILE__, __LINE__)

#undef strdup
#undef strndup

#define strdup __strdup_replaced
#define strndup __strndup_replaced

#endif // ZOSLIB_TRACE_ALLOCS

#include_next <string.h>

#if defined(ZOSLIB_TRACE_ALLOCS)
#undef strdup
#undef strndup
#define strdup __strdup_prtsrc
#define strndup __strndup_prtsrc
#endif

#ifdef __cplusplus
extern "C" {
#endif

__Z_EXPORT size_t strnlen(const char *, size_t );
__Z_EXPORT char *strpcpy(char *, const char *);
#if !defined(ZOSLIB_TRACE_ALLOCS)
__Z_EXPORT char *strndup(const char *s, size_t n);
#endif

__Z_EXPORT char *strsignal(int );
__Z_EXPORT const char *sigdescr_np(int);
Expand Down
41 changes: 35 additions & 6 deletions include/zos-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -571,12 +571,6 @@ unsigned long __get_libvec_base(void);
*/
__Z_EXPORT int __update_envar_names(zoslib_config_t *const config);

/**
* Tell zoslib that the main process is terminating, for its diagnostics.
*
*/
__Z_EXPORT void __mainTerminating();

/**
* Returns the program's directory as an absolute path
*/
Expand Down Expand Up @@ -703,4 +697,39 @@ template <std::size_t N> __Z_EXPORT std::bitset<N>
__zinit* __get_instance();

#endif // __cplusplus
#ifdef ZOSLIB_TRACE_ALLOCS
#ifdef __cplusplus
extern "C" {
#endif
__Z_EXPORT void heapreport();
__Z_EXPORT void *__zalloc_trace(size_t len, size_t alignment,
const char *pfname, int linenum);
__Z_EXPORT void *__zalloc_for_fd_trace(size_t len, const char *filename, int fd,
off_t offset,
const char *pfname, int linenum);
__Z_EXPORT void *anon_mmap_trace(void *_, size_t len,
const char *pfname, int linenum);
__Z_EXPORT void *roanon_mmap_trace(void *_, size_t len, int prot, int flags,
const char *filename, int fd, off_t offset,
const char *pfname, int linenum);
__Z_EXPORT void __display_alloc_stats(bool bDestroy, bool bDisplayAll);
#ifdef __cplusplus
}
#endif

#undef __zalloc
#undef __zalloc_for_fd
#undef anon_mmap
#undef roanon_mmap

#define __zalloc(len,alignment) \
__zalloc_trace(len,alignment,__FILE__,__LINE__)
#define __zalloc_for_fd(len,filename,fd,offset) \
__zalloc_for_fd_trace(len,filename,fd,offset,__FILE__,__LINE__)
#define anon_mmap(addr,len) \
anon_mmap_trace(addr,len,__FILE__,__LINE__)
#define roanon_mmap(addr,len,prot,flags,filename,fd,offset) \
roanon_mmap_trace(addr,len,prot,flags,filename,fd,offset,__FILE__,__LINE__)

#endif // ZOSLIB_TRACE_ALLOCS
#endif // ZOS_BASE_H_
31 changes: 24 additions & 7 deletions include/zos-io.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,30 +148,30 @@ __Z_EXPORT int __getfdccsid(int fd);
__Z_EXPORT int __setfdccsid(int fd, int t_ccsid);

/**
* Returns true if logging of memory allocation and release is specified.
* Returns true if logging of memory [de]allocation is specified.
*/
__Z_EXPORT bool __doLogMemoryUsage();

/**
* Returns the file name, including "stdout" or "stderr", used to log memory
* allocation and release to.
* [de]allocation to.
*/
__Z_EXPORT char *__getMemoryUsageLogFile();

/**
* Returns true if all messages from memory allocation and release are being
* Returns true if all messages from memory [de]allocation are being
* displayed.
*/
__Z_EXPORT bool __doLogMemoryAll();

/**
* Returns true if only warnings from memory allocation and release are being
* Returns true if only warnings from memory [de]allocation are being
* displayed. Errors are always included if memory logging in on.
*/
__Z_EXPORT bool __doLogMemoryWarning();

/**
* Returns true if memory allocation should be displayed when curval increases
* Returns true if memory allocation should be displayed when curvar increases
* by the value set in environment variable __MEMORY_USAGE_LOG_INC since the last
* currently allocated size was displayed.
*/
Expand All @@ -184,12 +184,29 @@ __Z_EXPORT bool __doLogMemoryInc(size_t curval, size_t *plastval);
__Z_EXPORT int __getLogMemoryFileNo();

/**
* Logs memory allocation and release to the file name specified
* in the environment variable zoslib_config_t.MEMORY_USAGE_LOG_FILE_ENVAR.
* Logs memory [de]allocation to the file name specified in the environment
* variable zoslib_config_t.MEMORY_USAGE_LOG_FILE_ENVAR.
* \param [in] same as C's printf() parameters
*/
__Z_EXPORT void __memprintf(const char *format, ...);

/**
* Logs memory [de]allocation to the file name specified in the environment
* variable zoslib_config_t.MEMORY_USAGE_LOG_FILE_ENVAR, but without the
* process-id or thread-id prefix as __memprintf does.
* \param [in] same as C's printf() parameters
*/
__Z_EXPORT void __memprintfx(const char *format, ...);

/**
* Returns the file name component of a given path.
* Similar to basename(path), but doesn't modify path, and if path ends with /,
* which is unexpected for a filename path, then it returns a pointer to that /.
* \param [in] path of a file.
* \return the file name component of a given path.
*/
__Z_EXPORT const char *__file_basename(const char *path);

#ifdef __cplusplus
}
#endif
Expand Down
8 changes: 8 additions & 0 deletions include/zos-sys-info.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,14 @@ __Z_EXPORT bool __is_vef1_available();
*/
__Z_EXPORT char *__get_cpu_model(char *buffer, size_t size);

/**
* Returns the current date and time as yyyy-mm-dd hh:mm:ss, so ts should
* be minimum char ts[20].
* \param ts pointer to the buffer where the timestemp is to be stored
* \return pointer to the buffer, or NULL if `sprintf()` failed.
*/
__Z_EXPORT char *__get_timestamp(char *ts);

__Z_EXPORT int getloadavg(double loadavg[], int nelem);

#ifdef __cplusplus
Expand Down
70 changes: 70 additions & 0 deletions include/zos-tsearch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
///////////////////////////////////////////////////////////////////////////////
// Licensed Materials - Property of IBM
// ZOSLIB
// (C) Copyright IBM Corp. 2024. All Rights Reserved.
// US Government Users Restricted Rights - Use, duplication
// or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
///////////////////////////////////////////////////////////////////////////////

#ifndef ZOS_TSEARCH_H_
#define ZOS_TSEARCH_H_

#if defined(ZOSLIB_TRACE_ALLOCS)

#include <sys/types.h>

typedef enum {
__MEMSPACE_64 = 1,
__MEMSPACE_64V,
__MEMSPACE_31
} __MEMSPACE;

typedef struct {
const void *addr;
size_t nbytes;
char *psrc;
size_t callnum; // the i'th time an alloc from location psrc was made
__MEMSPACE memspace;
} __taddr_t;

typedef struct {
char *psrc;
size_t curbytes; // # of bytes currently still allocated from this location
size_t maxbytes; // max # of bytes allocated from this location
size_t nallocs; // # of times an alloc has been called from this location
size_t nfrees; // # of times an alloc from this location has been freed
size_t lastrpt_curbytes; // last curbytes value displayed for stats
__MEMSPACE memspace;
} __tsrc_t;

#if defined(__cplusplus)
extern "C" {
#endif

const char *__bt_memspace_str(__MEMSPACE memspace);

// __bt_addr_* manipulate the binary search tree with memory address as key
void __bt_addr_add(void **pproot_addr, void **pproot_src, __taddr_t **ppnode,
__MEMSPACE memspace,
const void *addr, size_t nbytes,
const char *pfname, int linenum);
void __bt_addr_delete(void **pproot_addr, void **pproot_src,
const void *addr);
int __bt_addr_compare(const void *node1, const void *node2);
void __bt_addr_free_node( __taddr_t *pn);
__taddr_t *__bt_addr_find(void **pproot, const void *addr);

// __bt_src_* manipulate the binary search tree with alloc source:linenum as key
void __bt_src_add(void **pproot, __taddr_t *paddr_node);
int __bt_src_compare(const void *node1, const void *node2);
void __bt_src_free_node( __tsrc_t *pn);
void __bt_src_dec(void **pproot_src, const __taddr_t *paddr_node);
__tsrc_t *__bt_src_find(void **pproot, char *psrc);


#if defined(__cplusplus)
}
#endif

#endif
#endif
Loading