[DTrace-devel] [PATCH v2 14/20] fbt, syscall: use getline(), not fgets()

Nick Alcock nick.alcock at oracle.com
Wed Sep 7 13:00:01 UTC 2022


This lets us drop lots of code to handle too-long lines.  (Done for
consistency with the pid provider, which will do the same thing in a
subsequent commit.)

Signed-off-by: Nick Alcock <nick.alcock at oracle.com>
Reviewed-by: Eugene Loh <eugene.loh at oracle.com>
---
 libdtrace/dt_prov_fbt.c     | 20 +++++---------------
 libdtrace/dt_prov_syscall.c | 20 ++++----------------
 libdtrace/dt_provider_tp.c  | 14 +++++++++-----
 3 files changed, 18 insertions(+), 36 deletions(-)

diff --git a/libdtrace/dt_prov_fbt.c b/libdtrace/dt_prov_fbt.c
index 2a12e4ec49ea..72c31469df61 100644
--- a/libdtrace/dt_prov_fbt.c
+++ b/libdtrace/dt_prov_fbt.c
@@ -62,10 +62,10 @@ static int populate(dtrace_hdl_t *dtp)
 {
 	dt_provider_t		*prv;
 	FILE			*f;
-	char			buf[256];
+	char			*buf = NULL;
 	char			*p;
 	const char		*mod = modname;
-	int			n = 0;
+	size_t			n;
 	dtrace_syminfo_t	sip;
 	dtrace_probedesc_t	pd;
 
@@ -77,27 +77,16 @@ static int populate(dtrace_hdl_t *dtp)
 	if (f == NULL)
 		return 0;
 
-	while (fgets(buf, sizeof(buf), f)) {
+	while (getline(&buf, &n, f) >= 0) {
 		/*
 		 * Here buf is either "funcname\n" or "funcname [modname]\n".
+		 * The last line may not have a linefeed.
 		 */
 		p = strchr(buf, '\n');
 		if (p) {
 			*p = '\0';
 			if (p > buf && *(--p) == ']')
 				*p = '\0';
-		} else {
-			/*
-			 * If we didn't see a newline, the line was too long.
-			 * Report it, and skip until the end of the line.
-			 */
-			fprintf(stderr, "%s: Line too long: %s\n",
-				PROBE_LIST, buf);
-
-			do
-				fgets(buf, sizeof(buf), f);
-			while (strchr(buf, '\n') == NULL);
-			continue;
 		}
 
 		/*
@@ -142,6 +131,7 @@ static int populate(dtrace_hdl_t *dtp)
 			n++;
 	}
 
+	free(buf);
 	fclose(f);
 
 	return n;
diff --git a/libdtrace/dt_prov_syscall.c b/libdtrace/dt_prov_syscall.c
index d62c0e113d57..518340a9ad02 100644
--- a/libdtrace/dt_prov_syscall.c
+++ b/libdtrace/dt_prov_syscall.c
@@ -72,8 +72,8 @@ static int populate(dtrace_hdl_t *dtp)
 {
 	dt_provider_t	*prv;
 	FILE		*f;
-	char		buf[256];
-	int		n = 0;
+	char		*buf = NULL;
+	size_t		n;
 
 	prv = dt_provider_create(dtp, prvname, &dt_syscall, &pattr);
 	if (prv == NULL)
@@ -83,26 +83,13 @@ static int populate(dtrace_hdl_t *dtp)
 	if (f == NULL)
 		return 0;
 
-	while (fgets(buf, sizeof(buf), f)) {
+	while (getline(&buf, &n, f) >= 0) {
 		char	*p;
 
 		/* Here buf is "group:event".  */
 		p = strchr(buf, '\n');
 		if (p)
 			*p = '\0';
-		else {
-			/*
-			 * If we didn't see a newline, the line was too long.
-			 * Report it, and skip until the end of the line.
-			 */
-			fprintf(stderr, "%s: Line too long: %s\n",
-				PROBE_LIST, buf);
-			do
-				fgets(buf, sizeof(buf), f);
-			while (strchr(buf, '\n') == NULL);
-			continue;
-		}
-
 		/* We need "group:" to match "syscalls:". */
 		p = buf;
 		if (memcmp(p, PROV_PREFIX, sizeof(PROV_PREFIX) - 1) != 0)
@@ -127,6 +114,7 @@ static int populate(dtrace_hdl_t *dtp)
 		}
 	}
 
+	free(buf);
 	fclose(f);
 
 	return n;
diff --git a/libdtrace/dt_provider_tp.c b/libdtrace/dt_provider_tp.c
index 38504ed04f54..fdd7f9c5d4b3 100644
--- a/libdtrace/dt_provider_tp.c
+++ b/libdtrace/dt_provider_tp.c
@@ -1,6 +1,6 @@
 /*
  * Oracle Linux DTrace.
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
  * Licensed under the Universal Permissive License v 1.0 as shown at
  * http://oss.oracle.com/licenses/upl.
  *
@@ -120,7 +120,8 @@ int
 dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
 		 int *argcp, dt_argdesc_t **argvp)
 {
-	char		buf[1024];
+	char		*buf = NULL;
+	size_t		bufsz;
 	int		argc;
 	size_t		argsz = 0;
 	dt_argdesc_t	*argv = NULL;
@@ -139,7 +140,7 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
 	 * total size of all type strings together).
 	 */
 	argc = -skip;
-	while (fgets(buf, sizeof(buf), f)) {
+	while (getline(&buf, &bufsz, f) >= 0) {
 		char	*p = buf;
 
 		if (sscanf(buf, "ID: %d\n", &tpp->event_id) == 1)
@@ -159,6 +160,8 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
 		 */
 		argsz += strlen(p) + 1;
 	}
+	free(buf);
+	buf = NULL;
 
 	/*
 	 * If we saw less fields than expected, we flag an error.
@@ -183,7 +186,7 @@ dt_tp_event_info(dtrace_hdl_t *dtp, FILE *f, int skip, tp_probe_t *tpp,
 	 */
 	rewind(f);
 	argc = -skip;
-	while (fgets(buf, sizeof(buf), f)) {
+	while (getline(&buf, &bufsz, f) >= 0) {
 		char	*p = buf;
 		size_t	l;
 
@@ -255,6 +258,7 @@ skip:
 	}
 
 done:
+	free(buf);
 	*argcp = argc;
 	*argvp = argv;
 
@@ -263,7 +267,7 @@ done:
 
 /*
  * Detach from a tracepoint for a tracepoint-based probe.  The caller should
- * still call dt_tp_destroy() to free the tracepointe-specific probe data.
+ * still call dt_tp_destroy() to free the tracepoint-specific probe data.
  */
 void
 dt_tp_detach(dtrace_hdl_t *dtp, tp_probe_t *tpp)
-- 
2.37.1.265.g363c192786.dirty




More information about the DTrace-devel mailing list