All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] perf ctf: Convert invalid chars in a string before set value
@ 2016-05-27 11:35 Wang Nan
  2016-05-27 15:53 ` Arnaldo Carvalho de Melo
  2016-05-29 18:20 ` [tip:perf/urgent] " tip-bot for Wang Nan
  0 siblings, 2 replies; 3+ messages in thread
From: Wang Nan @ 2016-05-27 11:35 UTC (permalink / raw)
  To: jolsa, acme
  Cc: pi3orama, linux-kernel, Wang Nan, Arnaldo Carvalho de Melo,
	Jiri Olsa

We observed some crazy apps on Android set their comm to unprintable
string. For example:

  # cat /proc/10607/task/*/comm
  tencent.qqmusic
  ...
  Binder_2
  日志输出线  <-- Chinese word 'log output thread'
  WifiManager
  ...

'perf data convert' fails to convert perf.data with such string to CTF format.

For example:
 # cat << EOF > ./badguy.c
 #include <sys/prctl.h>
 int main(int argc, char *argv[])
 {
         prctl(PR_SET_NAME, "\xe6\x97\xa5\xe5\xbf\x97\xe8\xbe\x93\xe5\x87\xba\xe7\xba\xbf");
         while(1)
                 sleep(1);
         return 0;
 }
 EOF
 # gcc ./badguy.c
 # perf record -e sched:* ./a.out
 # perf data convert --to-ctf ./bad.ctf
 CTF stream 4 flush failed
 [ perf data convert: Converted 'perf.data' into CTF data './bad.ctf' ]
 [ perf data convert: Converted and wrote 0.008 MB (78 samples)  ]
 # babeltrace ./bad.ctf/
 [error] Packet size (18446744073709551615 bits) is larger than remaining file size (262144 bits).
 [error] Stream index creation error.
 [error] Open file stream error.
 [warning] [Context] Cannot open_trace of format ctf at path ./bad.ctf.
 [warning] [Context] cannot open trace "./bad.ctf" from ./bad.ctf/ for reading.
 [error] Cannot open any trace for reading.

 [error] opening trace "./bad.ctf/" for reading.

 [error] none of the specified trace paths could be opened.

This patch converts unprintable characters to hexadecimal word.

After applying this patch the above test works correctly:

  # ~/perf data convert --to-ctf ./good.ctf
  [ perf data convert: Converted 'perf.data' into CTF data './good.ctf' ]
  [ perf data convert: Converted and wrote 0.008 MB (78 samples) ]
  # babeltrace ./good.ctf
  ..
  [23:14:35.491665268] (+0.000001100) sched:sched_wakeup: { cpu_id = 4 }, { perf_ip = 0xFFFFFFFF810AEF33, perf_tid = 0, perf_pid = 0, perf_id = 5123, perf_period = 1, common_type = 270, common_flags = 45, common_preempt_count = 4, common_pid = 0, comm = "\xe6\x97\xa5\xe5\xbf\x97\xe8\xbe\x93\xe5\x87\xba\xe7\xba\xbf", pid = 1057, prio = 120, success = 1, target_cpu = 4 }
 [23:14:35.491666230] (+0.000000962) sched:sched_wakeup: { cpu_id = 4 }, { perf_ip = 0xFFFFFFFF810AEF33, perf_tid = 0, perf_pid = 0, perf_id = 5122, perf_period = 1, common_type = 270, common_flags = 45, common_preempt_count = 4, common_pid = 0, comm = "\xe6\x97\xa5\xe5\xbf\x97\xe8\xbe\x93\xe5\x87\xba\xe7\xba\xbf", pid = 1057, prio = 120, success = 1, target_cpu = 4 }
  ..

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---

v1 -> v2: Alloc buffer only when a unprintable char is observed:
          most of the time string is printable.

	  Jiri, can I have your Acked-by again?

---
 tools/perf/util/data-convert-bt.c | 41 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index bbf69d2..9f53020 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -204,6 +204,44 @@ static unsigned long long adjust_signedness(unsigned long long value_int, int si
 	return (value_int & value_mask) | ~value_mask;
 }
 
+static int string_set_value(struct bt_ctf_field *field, const char *string)
+{
+	char *buffer = NULL;
+	size_t len = strlen(string), i, p;
+	int err;
+
+	for (i = p = 0; i < len; i++, p++) {
+		if (isprint(string[i])) {
+			if (!buffer)
+				continue;
+			buffer[p] = string[i];
+		} else {
+			char numstr[5];
+
+			snprintf(numstr, sizeof(numstr), "\\x%02x",
+				 (unsigned int)(string[i]) & 0xff);
+
+			if (!buffer) {
+				buffer = zalloc(i + (len - i) * 4 + 2);
+				if (!buffer) {
+					pr_err("failed to set unprintable string '%s'\n", string);
+					return bt_ctf_field_string_set_value(field, "UNPRINTABLE-STRING");
+				}
+				if (i > 0)
+					strncpy(buffer, string, i);
+			}
+			strncat(buffer + p, numstr, 4);
+			p += 3;
+		}
+	}
+
+	if (!buffer)
+		return bt_ctf_field_string_set_value(field, string);
+	err = bt_ctf_field_string_set_value(field, buffer);
+	free(buffer);
+	return err;
+}
+
 static int add_tracepoint_field_value(struct ctf_writer *cw,
 				      struct bt_ctf_event_class *event_class,
 				      struct bt_ctf_event *event,
@@ -270,8 +308,7 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
 		}
 
 		if (flags & FIELD_IS_STRING)
-			ret = bt_ctf_field_string_set_value(field,
-					data + offset + i * len);
+			ret = string_set_value(field, data + offset + i * len);
 		else {
 			unsigned long long value_int;
 
-- 
1.8.3.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2] perf ctf: Convert invalid chars in a string before set value
  2016-05-27 11:35 [PATCH v2] perf ctf: Convert invalid chars in a string before set value Wang Nan
@ 2016-05-27 15:53 ` Arnaldo Carvalho de Melo
  2016-05-29 18:20 ` [tip:perf/urgent] " tip-bot for Wang Nan
  1 sibling, 0 replies; 3+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-05-27 15:53 UTC (permalink / raw)
  To: Wang Nan; +Cc: jolsa, pi3orama, linux-kernel, Arnaldo Carvalho de Melo,
	Jiri Olsa

Em Fri, May 27, 2016 at 11:35:51AM +0000, Wang Nan escreveu:
> We observed some crazy apps on Android set their comm to unprintable
> string. For example:
> 
>   # cat /proc/10607/task/*/comm
>   tencent.qqmusic
>   ...
>   Binder_2
>   日志输出线  <-- Chinese word 'log output thread'
>   WifiManager
>   ...
> 
> 'perf data convert' fails to convert perf.data with such string to CTF format.

Thanks, tested and applied to perf/urgent.

- Arnaldo

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [tip:perf/urgent] perf ctf: Convert invalid chars in a string before set value
  2016-05-27 11:35 [PATCH v2] perf ctf: Convert invalid chars in a string before set value Wang Nan
  2016-05-27 15:53 ` Arnaldo Carvalho de Melo
@ 2016-05-29 18:20 ` tip-bot for Wang Nan
  1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for Wang Nan @ 2016-05-29 18:20 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: wangnan0, jolsa, hpa, mingo, acme, linux-kernel, tglx

Commit-ID:  5ea5888b2fbf5b230da62b2a21c8247bebb6c9cf
Gitweb:     http://git.kernel.org/tip/5ea5888b2fbf5b230da62b2a21c8247bebb6c9cf
Author:     Wang Nan <wangnan0@huawei.com>
AuthorDate: Fri, 27 May 2016 11:35:51 +0000
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 27 May 2016 12:08:40 -0300

perf ctf: Convert invalid chars in a string before set value

We observed some crazy apps on Android set their comm to unprintable
string. For example:

  # cat /proc/10607/task/*/comm
  tencent.qqmusic
  ...
  Binder_2
  日志输出线  <-- Chinese word 'log output thread'
  WifiManager
  ...

'perf data convert' fails to convert perf.data with such string to CTF format.

For example:

  # cat << EOF > ./badguy.c
  #include <sys/prctl.h>
  int main(int argc, char *argv[])
  {
         prctl(PR_SET_NAME, "\xe6\x97\xa5\xe5\xbf\x97\xe8\xbe\x93\xe5\x87\xba\xe7\xba\xbf");
         while(1)
                 sleep(1);
         return 0;
  }
  EOF
  # gcc ./badguy.c
  # perf record -e sched:* ./a.out
  # perf data convert --to-ctf ./bad.ctf
  CTF stream 4 flush failed
  [ perf data convert: Converted 'perf.data' into CTF data './bad.ctf' ]
  [ perf data convert: Converted and wrote 0.008 MB (78 samples)  ]
  # babeltrace ./bad.ctf/
  [error] Packet size (18446744073709551615 bits) is larger than remaining file size (262144 bits).
  [error] Stream index creation error.
  [error] Open file stream error.
  [warning] [Context] Cannot open_trace of format ctf at path ./bad.ctf.
  [warning] [Context] cannot open trace "./bad.ctf" from ./bad.ctf/ for reading.
  [error] Cannot open any trace for reading.

  [error] opening trace "./bad.ctf/" for reading.

  [error] none of the specified trace paths could be opened.

This patch converts unprintable characters to hexadecimal word.

After applying this patch the above test works correctly:

  # ~/perf data convert --to-ctf ./good.ctf
  [ perf data convert: Converted 'perf.data' into CTF data './good.ctf' ]
  [ perf data convert: Converted and wrote 0.008 MB (78 samples) ]
  # babeltrace ./good.ctf
  ..
  [23:14:35.491665268] (+0.000001100) sched:sched_wakeup: { cpu_id = 4 }, { perf_ip = 0xFFFFFFFF810AEF33, perf_tid = 0, perf_pid = 0, perf_id = 5123, perf_period = 1, common_type = 270, common_flags = 45, common_preempt_count = 4, common_pid = 0, comm = "\xe6\x97\xa5\xe5\xbf\x97\xe8\xbe\x93\xe5\x87\xba\xe7\xba\xbf", pid = 1057, prio = 120, success = 1, target_cpu = 4 }
  [23:14:35.491666230] (+0.000000962) sched:sched_wakeup: { cpu_id = 4 }, { perf_ip = 0xFFFFFFFF810AEF33, perf_tid = 0, perf_pid = 0, perf_id = 5122, perf_period = 1, common_type = 270, common_flags = 45, common_preempt_count = 4, common_pid = 0, comm = "\xe6\x97\xa5\xe5\xbf\x97\xe8\xbe\x93\xe5\x87\xba\xe7\xba\xbf", pid = 1057, prio = 120, success = 1, target_cpu = 4 }
  ..

Committer note:

To build perf with libabeltrace, use:

  $ mkdir -p /tmp/build/perf
  $ make LIBBABELTRACE=1 LIBBABELTRACE_DIR=/usr/local O=/tmp/build/perf -C tools/perf install-bin

Or equivalent (no O=, fixup LIBBABELTRACE_DIR, etc).

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1464348951-179595-1-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/data-convert-bt.c | 41 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index bbf69d2..9f53020 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -204,6 +204,44 @@ static unsigned long long adjust_signedness(unsigned long long value_int, int si
 	return (value_int & value_mask) | ~value_mask;
 }
 
+static int string_set_value(struct bt_ctf_field *field, const char *string)
+{
+	char *buffer = NULL;
+	size_t len = strlen(string), i, p;
+	int err;
+
+	for (i = p = 0; i < len; i++, p++) {
+		if (isprint(string[i])) {
+			if (!buffer)
+				continue;
+			buffer[p] = string[i];
+		} else {
+			char numstr[5];
+
+			snprintf(numstr, sizeof(numstr), "\\x%02x",
+				 (unsigned int)(string[i]) & 0xff);
+
+			if (!buffer) {
+				buffer = zalloc(i + (len - i) * 4 + 2);
+				if (!buffer) {
+					pr_err("failed to set unprintable string '%s'\n", string);
+					return bt_ctf_field_string_set_value(field, "UNPRINTABLE-STRING");
+				}
+				if (i > 0)
+					strncpy(buffer, string, i);
+			}
+			strncat(buffer + p, numstr, 4);
+			p += 3;
+		}
+	}
+
+	if (!buffer)
+		return bt_ctf_field_string_set_value(field, string);
+	err = bt_ctf_field_string_set_value(field, buffer);
+	free(buffer);
+	return err;
+}
+
 static int add_tracepoint_field_value(struct ctf_writer *cw,
 				      struct bt_ctf_event_class *event_class,
 				      struct bt_ctf_event *event,
@@ -270,8 +308,7 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
 		}
 
 		if (flags & FIELD_IS_STRING)
-			ret = bt_ctf_field_string_set_value(field,
-					data + offset + i * len);
+			ret = string_set_value(field, data + offset + i * len);
 		else {
 			unsigned long long value_int;
 

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-05-29 18:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-05-27 11:35 [PATCH v2] perf ctf: Convert invalid chars in a string before set value Wang Nan
2016-05-27 15:53 ` Arnaldo Carvalho de Melo
2016-05-29 18:20 ` [tip:perf/urgent] " tip-bot for Wang Nan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.