linux-kernel.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).