add exe and cwd to proc_begin
Stefan Schuermans

Stefan Schuermans commited on 2020-05-17 11:16:27
Showing 9 changed files, with 224 additions and 14 deletions.

... ...
@@ -14,7 +14,14 @@ add_library(
14 14
   lwpttr
15 15
   STATIC
16 16
   include/liblwpttr/event.h
17
+  src/cleaner.c
18
+  src/cleaner.h
17 19
   src/event.c
20
+  src/macros.h
21
+  src/symlink.c
22
+  src/symlink.h
23
+  src/timestamp.c
24
+  src/timestamp.h
18 25
   ${CMAKE_CURRENT_BINARY_DIR}/src/lwproctrace.pb-c.c
19 26
   ${CMAKE_CURRENT_BINARY_DIR}/src/lwproctrace.pb-c.h
20 27
 )
... ...
@@ -0,0 +1,56 @@
1
+#include "cleaner.h"
2
+#include "macros.h"
3
+
4
+#include <stdlib.h>
5
+
6
+struct lwpttr_cleaner_s {
7
+  unsigned int free_ptr_cnt; /**< number of pointer to be freed */
8
+  void * free_ptrs[64]; /**< pointers to be freed */
9
+  lwpttr_cleaner_t *next; /**< next cleaner object, linked list */
10
+};
11
+
12
+lwpttr_cleaner_t * lwpttr_cleaner_new(void) {
13
+  lwpttr_cleaner_t *cleaner = malloc(sizeof(lwpttr_cleaner_t));
14
+  if (! cleaner) {
15
+    return NULL;
16
+  }
17
+  cleaner->free_ptr_cnt = 0;
18
+  cleaner->next = NULL;
19
+  return cleaner;
20
+}
21
+
22
+int lwpttr_cleaner_add_ptr(lwpttr_cleaner_t *cleaner, void *ptr) {
23
+  /* find last cleaner in chain */
24
+  lwpttr_cleaner_t *cl = cleaner;
25
+  while (cl->next != NULL) {
26
+    cl = cl->next;
27
+  }
28
+  /* last cleaner full? */
29
+  if (cl->free_ptr_cnt >= countof(cl->free_ptrs)) {
30
+    /* create new one */
31
+    cl->next = lwpttr_cleaner_new();
32
+    /* error ? */
33
+    if (! cl->next) {
34
+      /* cleanup everything and reutrn error */
35
+      lwpttr_cleaner_cleanup(cleaner);
36
+      return -1;
37
+    }
38
+    /* go to new cleaner */
39
+    cl = cl->next;
40
+  }
41
+  /* add pointer */
42
+  cl->free_ptrs[cl->free_ptr_cnt++] = ptr;
43
+  return 0;
44
+}
45
+
46
+void lwpttr_cleaner_cleanup(lwpttr_cleaner_t *cleaner) {
47
+  lwpttr_cleaner_t *cl = cleaner;
48
+  while (cl) {
49
+    /* free all pointers in cleaner */
50
+    for (unsigned int i = 0; i < cl->free_ptr_cnt; ++i) {
51
+      free(cl->free_ptrs[i]);
52
+    }
53
+    /* move to next cleaner */
54
+    cl = cl->next;
55
+  }
56
+}
... ...
@@ -0,0 +1,32 @@
1
+#ifndef LWPTTR_CLEANER_H
2
+#define LWPTTR_CLEANER_H
3
+
4
+/**
5
+ * @brief cleaner object
6
+ *
7
+ * collects pointers to be freed and frees them on request
8
+ */
9
+typedef struct lwpttr_cleaner_s lwpttr_cleaner_t;
10
+
11
+/**
12
+ * @brief creater cleaner object
13
+ * @return pointer to cleaner object or NULL on error
14
+ */
15
+lwpttr_cleaner_t * lwpttr_cleaner_new(void);
16
+
17
+/**
18
+ * @brief add pointer to be freed to cleaner object
19
+ * @param[in] cleaner cleaner object
20
+ * @param[in] ptr the pointer to be freed on cleanup
21
+ * @return 0 on success, -1 on error
22
+ *         (on error, cleanup is done and cleaner is deallocated)
23
+ */
24
+int lwpttr_cleaner_add_ptr(lwpttr_cleaner_t *cleaner, void *ptr);
25
+
26
+/**
27
+ * @brief cleanup all pointers in cleaner and free cleaner itself
28
+ * @param[in] cleaner cleaner object
29
+ */
30
+void lwpttr_cleaner_cleanup(lwpttr_cleaner_t *cleaner);
31
+
32
+#endif /* #ifndef LWPTTR_CLEANER_H */
... ...
@@ -1,35 +1,55 @@
1 1
 #include <liblwpttr/event.h>
2
+#include "cleaner.h"
3
+#include "symlink.h"
4
+#include "timestamp.h"
2 5
 
3 6
 #include <lwproctrace.pb-c.h>
4 7
 
5 8
 #include <stdlib.h>
6 9
 #include <sys/types.h>
7
-#include <time.h>
8 10
 #include <unistd.h>
9 11
 
12
+static int lwpttr_event_pack(struct _Lwproctrace__Event *event,
13
+                             void **data, size_t *size,
14
+                             lwpttr_cleaner_t *cleaner) {
15
+  *size = lwproctrace__event__get_packed_size(event);
16
+  *data = malloc(*size);
17
+  if (! data) {
18
+    lwpttr_cleaner_cleanup(cleaner);
19
+    *size = 0;
20
+    return -1;
21
+  }
22
+  *size = lwproctrace__event__pack(event, *data);
23
+  lwpttr_cleaner_cleanup(cleaner);
24
+  return 0;
25
+}
26
+
10 27
 int lwpttr_event_proc_begin(void **data, size_t *size) {
11
-  struct timespec now;
12
-  clock_gettime(CLOCK_REALTIME, &now);
28
+  *data = NULL;
29
+  *size = 0;
30
+
31
+  lwpttr_cleaner_t *cleaner = lwpttr_cleaner_new();
32
+  if (! cleaner) {
33
+    return -1;
34
+  }
35
+
13 36
   struct _Lwproctrace__Timespec timestamp = LWPROCTRACE__TIMESPEC__INIT;
14
-  timestamp.sec = now.tv_sec;
15
-  timestamp.has_nsec = 1;
16
-  timestamp.nsec = now.tv_nsec;
37
+  lwpttr_event_get_timestamp(&timestamp);
17 38
 
18 39
   struct _Lwproctrace__ProcBegin proc_begin = LWPROCTRACE__PROC_BEGIN__INIT;
19 40
   proc_begin.pid = getpid();
20 41
   proc_begin.has_ppid = 1;
21 42
   proc_begin.ppid = getppid();
43
+  if (symlink_read("/proc/self/exe", &proc_begin.exe, cleaner) != 0) {
44
+    return -1;
45
+  }
46
+  if (symlink_read("/proc/self/cwd", &proc_begin.cwd, cleaner) != 0) {
47
+    return -1;
48
+  }
22 49
 
23 50
   struct _Lwproctrace__Event event = LWPROCTRACE__EVENT__INIT;
24 51
   event.timestamp = &timestamp;
25 52
   event.proc_begin = &proc_begin;
26 53
 
27
-  *size = lwproctrace__event__get_packed_size(&event);
28
-  *data = malloc(*size);
29
-  if (! data) {
30
-    *size = 0;
31
-    return -1;
32
-  }
33
-  lwproctrace__event__pack(&event, *data);
34
-  return 0;
54
+  return lwpttr_event_pack(&event, data, size, cleaner);
35 55
 }
... ...
@@ -0,0 +1,6 @@
1
+#ifndef LWPTTR_MACROS_H
2
+#define LWPTTR_MACROS_H
3
+
4
+#define countof(arr) (sizeof(arr) / sizeof((arr)[0]))
5
+
6
+#endif /* #ifndef LWPTTR_MACROS_H */
... ...
@@ -0,0 +1,47 @@
1
+#include "symlink.h"
2
+#include "cleaner.h"
3
+
4
+#include <stdlib.h>
5
+#include <unistd.h>
6
+
7
+/**
8
+ * @brief read target of symlink
9
+ * @param[in] pathname path to symbolic link
10
+ * @return malloc-ed string containting link target or NULL
11
+ */
12
+static char * symlink_read_target(char const *pathname) {
13
+  size_t sz = 256;
14
+  char *target = NULL;
15
+  while (1) {
16
+    /* get buffer */
17
+    target = malloc(sz);
18
+    if (! target) {
19
+      return NULL;
20
+    }
21
+    /* get link target */
22
+    ssize_t len = readlink(pathname, target, sz);
23
+    if (len < 0) {
24
+      free(target);
25
+      return NULL;
26
+    }
27
+    /* link target fit into buffer -> terminate string and return */
28
+    if ((size_t)len + 1 < sz) {
29
+      target[len] = 0;
30
+      return target;
31
+    }
32
+    /* free buffer and try again with larger buffer */
33
+    free(target);
34
+    sz *= 2;
35
+  }
36
+}
37
+
38
+int symlink_read(char const *pathname, char **target,
39
+                 lwpttr_cleaner_t *cleaner) {
40
+  *target = symlink_read_target(pathname);
41
+  if (! *target) {
42
+    lwpttr_cleaner_cleanup(cleaner);
43
+    return -1;
44
+  }
45
+  lwpttr_cleaner_add_ptr(cleaner, *target);
46
+  return 0;
47
+}
... ...
@@ -0,0 +1,17 @@
1
+#ifndef LWPTTR_SYMLINK_H
2
+#define LWPTTR_SYMLINK_H
3
+
4
+#include "cleaner.h"
5
+
6
+/**
7
+ * @brief read symlink
8
+ * @param[in] pathname path to symbolic link
9
+ * @param[out] *target malloc-ed string object containing symlink target
10
+ * @param[in,out] cleaner object, malloc-ed string is added to it
11
+ * @return 0 on success, -1 on error
12
+ *         (on error, cleanup is done and cleaner is deallocated)
13
+ */
14
+int symlink_read(char const *pathname, char **target,
15
+                 lwpttr_cleaner_t *cleaner);
16
+
17
+#endif /* #ifndef LWPTTR_SYMLINK_H */
... ...
@@ -0,0 +1,13 @@
1
+#include "timestamp.h"
2
+
3
+#include <lwproctrace.pb-c.h>
4
+
5
+#include <time.h>
6
+
7
+void lwpttr_event_get_timestamp(struct _Lwproctrace__Timespec *timestamp) {
8
+  struct timespec now;
9
+  clock_gettime(CLOCK_REALTIME, &now);
10
+  timestamp->sec = now.tv_sec;
11
+  timestamp->has_nsec = 1;
12
+  timestamp->nsec = now.tv_nsec;
13
+}
... ...
@@ -0,0 +1,12 @@
1
+#ifndef LWPTTR_TIMESTAMP_H
2
+#define LWPTTR_TIMESTAMP_H
3
+
4
+#include <lwproctrace.pb-c.h>
5
+
6
+/**
7
+ * @brief fill timestamp with current time
8
+ * @param[in,out] timestamp initialized structure to set to current time
9
+ */
10
+void lwpttr_event_get_timestamp(struct _Lwproctrace__Timespec *timestamp);
11
+
12
+#endif /* #ifndef LWPTTR_TIMESTAMP_H */
0 13