---
00-README.conf | 13 ++++-
Makefile.am | 8 ++-
README | 1 +
configure.ac | 18 ++++++
src/base/daemon.c | 96 +++++++++++++++++++++++++++++--
src/nid/opensafd.in | 7 +++
tools/devel/gcov_collect/osaf_gcov_dump.c | 40 +++++++++++++
7 files changed, 176 insertions(+), 7 deletions(-)
create mode 100644 tools/devel/gcov_collect/osaf_gcov_dump.c
diff --git a/00-README.conf b/00-README.conf
index f64aa031c..c42a37563 100644
--- a/00-README.conf
+++ b/00-README.conf
@@ -610,4 +610,15 @@ A message will be written if the latency is > 0.1 second,
example below shows a
messages.1:Sep 12 13:09:26 SC-1 osafimmd[26732]: NO MDS timerfd expired 10
times
-If the latency exceeds 4 seconds a sigalrm will be sent and the process will
be aborted.
\ No newline at end of file
+If the latency exceeds 4 seconds a sigalrm will be sent and the process will
be aborted.
+
+# To enable gcov run ./configure --enable-gcov
+# In each daemon a thread will be created that listens to a default multicast
group 239.0.0.1 port 4712.
+# To change default, update /etc/init.d/opensafd setup_env function, example:
+# export OPENSAF_GCOV_MULTICAST_GROUP="224.0.0.1"
+# export OPENSAF_GCOV_MULTICAST_PORT="4711"
+# and if running in UML uncomment the line:
+# echo 100 > /proc/sys/net/ipv4/igmp_max_memberships
+# To collect gcov data use program tools/develop/gcov_collect/osaf_gcov_dump.
+# Check the MULTICAST_PORT and MULTICAST_GROUP settings are the same as
multicast group and port
+# above.
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
index 7763f313c..0a69f752d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -56,7 +56,13 @@ AM_CPPFLAGS = \
AM_CFLAGS = -pipe -std=gnu11 @OSAF_HARDEN_FLAGS@ -Wall -Wformat=2 -Werror
AM_CXXFLAGS = -pipe -std=gnu++11 @OSAF_HARDEN_FLAGS@ -Wall -Wformat=2 -Werror
-AM_LDFLAGS = @OSAF_HARDEN_FLAGS@ -Wl,--as-needed -ldl -lrt -pthread -rdynamic
+
+if ENABLE_GCOV
+AM_CFLAGS += --coverage
+AM_CXXFLAGS += --coverage
+endif
+
+AM_LDFLAGS = @OSAF_HARDEN_FLAGS@ -Wl,--as-needed -ldl -lrt -pthread -rdynamic
-lgcov
ACLOCAL_AMFLAGS = -I m4
OSAF_LIB_FLAGS =
diff --git a/README b/README
index 13c0eb352..d51314a4b 100644
--- a/README
+++ b/README
@@ -534,6 +534,7 @@ available w.r.t enabling/disabling the build for a
particular OpenSAF service:
produced.
--disable-rpm-target disable support for the "make rpm" target
[default=no]
+ --enable-gcov enable code coverage [default=no]
--enable-experimental enable experimental code [default=no]
--enable-python enable the Python AIS bindings [default=yes]
--enable-java enable the Java AIS interface mapping [default=no]
diff --git a/configure.ac b/configure.ac
index 74655ddce..56b17ab36 100644
--- a/configure.ac
+++ b/configure.ac
@@ -188,6 +188,24 @@ fi
AM_CONDITIONAL([ENABLE_EXPERIMENTAL], [test "$enable_experimental" = yes])
AC_SUBST([EXPERIMENTAL_ENABLED], ["$enable_experimental"])
+#
+# Enable/disable gcov
+#
+AC_MSG_CHECKING([whether to build with gcov])
+AC_ARG_ENABLE([gcov],
+ [AS_HELP_STRING([--enable-gcov],
+ [enable building with gcov [default=no]])],
+ [],
+ [enable_gcov=no])
+AC_MSG_RESULT([$enable_gcov])
+
+if test "$enable_gcov" = yes; then
+ AC_DEFINE([ENABLE_GCOV], 1, [Define if gcov is enabled])
+fi
+
+AM_CONDITIONAL([ENABLE_GCOV], [test "$enable_gcov" = yes])
+AC_SUBST([GCOV_ENABLED], ["$enable_gcov"])
+
#
# Enable/disable the Python AIS bindings
#
diff --git a/src/base/daemon.c b/src/base/daemon.c
index 575588575..3e6ca7357 100644
--- a/src/base/daemon.c
+++ b/src/base/daemon.c
@@ -15,7 +15,13 @@
* Author(s): Wind River Systems
*
*/
+#ifdef HAVE_CONFIG_H
+#include "osaf/config.h"
+#endif
+#include <pthread.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <ctype.h>
#include <sched.h>
#include <stdio.h>
@@ -56,8 +62,6 @@
static const char *internal_version_id_;
-extern void __gcov_flush(void) __attribute__((weak));
-
static char fifo_file[NAME_MAX];
static char __pidfile[NAME_MAX];
static char __tracefile[NAME_MAX];
@@ -69,6 +73,87 @@ static int fifo_fd = -1;
static void install_fatal_signal_handlers(void);
+#ifdef ENABLE_GCOV
+
+// default multicast group for gcov collection
+#define DFLT_MULTICAST_GROUP "239.0.0.1"
+
+extern void __gcov_dump();
+extern void __gcov_reset();
+
+static void* gcov_flush_thread(void* arg) {
+ int listenfd;
+ const int on = 1;
+ struct sockaddr_in servaddr;
+ struct ip_mreq mreq;
+ char buf[40];
+ struct sockaddr_in addr;
+ socklen_t addr_len;
+ int multicast_port = 4712; // default multicast group for gcov
collection
+ const char *multicast_port_str;
+ const char *multicast_group;
+
+ if ((multicast_group = getenv("OPENSAF_GCOV_MULTICAST_GROUP")) == NULL)
{
+ multicast_group = DFLT_MULTICAST_GROUP;
+ }
+
+ if ((multicast_port_str = getenv("OPENSAF_GCOV_MULTICAST_PORT")) !=
NULL) {
+ multicast_port = strtol(multicast_port_str, NULL, 0);
+ }
+
+ listenfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ if ((setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) ==
-1)) {
+ syslog(LOG_ERR, "%s: setsockpot failed: %s", __FUNCTION__,
strerror(errno));
+ return 0;
+ }
+
+ memset(&servaddr, 0, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ servaddr.sin_port = htons(multicast_port);
+
+ if (bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0)
{
+ syslog(LOG_ERR, "%s: bind failed: %s", __FUNCTION__,
strerror(errno));
+ return 0;
+ }
+
+ //
+ mreq.imr_multiaddr.s_addr=inet_addr(multicast_group);
+ mreq.imr_interface.s_addr=htonl(INADDR_ANY);
+ if (setsockopt(listenfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(mreq)) < 0) {
+ syslog(LOG_ERR, "%s: setsockopt failed: %s", __FUNCTION__,
strerror(errno));
+ return 0;
+ } else {
+ syslog(LOG_NOTICE, "%s: joined multicast group %s port %d\n",
+ __FUNCTION__, multicast_group, multicast_port);
+ }
+
+ for(;;) {
+ addr_len = sizeof(addr);
+ recvfrom(listenfd, &buf, sizeof(buf), 0, (struct sockaddr *)
&addr, &addr_len);
+ __gcov_dump();
+ __gcov_reset();
+ syslog(LOG_NOTICE, "__gov_dump() and __gcov_reset() called");
+ }
+ return 0;
+};
+
+static void create_gcov_flush_thread(void) {
+ pthread_t thread;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if (pthread_create(&thread, &attr, gcov_flush_thread, 0) != 0) {
+ syslog(LOG_ERR, "pthread_create FAILED: %s", strerror(errno));
+ }
+
+ pthread_attr_destroy(&attr);
+}
+
+#endif
+
static void __print_usage(const char *progname, FILE *stream, int exit_code)
{
fprintf(stream, "Usage: %s [OPTIONS]...\n", progname);
@@ -398,6 +483,10 @@ void daemonize(int argc, char *argv[])
create_fifofile(fifo_file);
+#ifdef ENABLE_GCOV
+ create_gcov_flush_thread();
+#endif
+
/* Create the process PID file */
if (__create_pidfile(__pidfile) != 0)
exit(EXIT_FAILURE);
@@ -537,9 +626,6 @@ void daemon_exit(void)
unlink(fifo_file);
unlink(__pidfile);
- if (__gcov_flush) {
- __gcov_flush();
- }
_Exit(0);
}
diff --git a/src/nid/opensafd.in b/src/nid/opensafd.in
index 428b222c2..effe87d41 100644
--- a/src/nid/opensafd.in
+++ b/src/nid/opensafd.in
@@ -72,6 +72,13 @@ check_tipc() {
}
setup_env() {
+ # The following lines if --enable-gcov is configured
+ # If running in UML uncomment the next line
+ # echo 100 > /proc/sys/net/ipv4/igmp_max_memberships
+ # gcov collecton is using multicast, to change default multicast group
and multicast group:
+ # export OPENSAF_GCOV_MULTICAST_GROUP="224.0.0.1"
+ # export OPENSAF_GCOV_MULTICAST_PORT="4711"
+
# Make sure this kernel has POSIX shared memory configured
if [ ! -d /dev/shm ]; then
logger -s -t $osafprog "POSIX shared memory (/dev/shm) not
enabled, exiting."
diff --git a/tools/devel/gcov_collect/osaf_gcov_dump.c
b/tools/devel/gcov_collect/osaf_gcov_dump.c
new file mode 100644
index 000000000..9999d2b51
--- /dev/null
+++ b/tools/devel/gcov_collect/osaf_gcov_dump.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+// gcc -g -o osaf_gcov_dump osaf_gcov_dump.c
+#define MULTICAST_PORT 4712
+#define MULTICAST_GROUP "239.0.0.1"
+
+int main()
+{
+ struct sockaddr_in addr;
+ int fd, cnt;
+ struct ip_mreq mreq;
+ const char message[] = "Not used";
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM,0)) < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+ memset(&addr,0,sizeof(addr));
+ addr.sin_family=AF_INET;
+ addr.sin_addr.s_addr=inet_addr(MULTICAST_GROUP);
+ addr.sin_port=htons(MULTICAST_PORT);
+
+ if (sendto(fd, message, sizeof(message), 0, (struct sockaddr *) &addr,
+ sizeof(addr)) < 0) {
+ perror("sendto");
+ } else {
+ printf("sendto %s %d ok!\n", MULTICAST_GROUP, MULTICAST_PORT);
+ }
+ return 0;
+}
--
2.14.1
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel