linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@redhat.com>
To: Stephane Eranian <eranian@google.com>
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
	mingo@elte.hu, ak@linux.intel.com, jolsa@redhat.com,
	namhyung@kernel.org, cel@us.ibm.com, sukadev@linux.vnet.ibm.com,
	sonnyrao@chromium.org, johnmccutchan@google.com,
	dsahern@gmail.com, adrian.hunter@intel.com, pawel.moll@arm.com
Subject: Re: [PATCH v4 2/4] perf tools: add Java demangling support
Date: Wed, 25 Mar 2015 19:18:45 -0300	[thread overview]
Message-ID: <20150325221845.GC2161@redhat.com> (raw)
In-Reply-To: <1427235933-949-3-git-send-email-eranian@google.com>

Em Tue, Mar 24, 2015 at 11:25:31PM +0100, Stephane Eranian escreveu:

<SNIP>

> +static char *
> +__demangle_java_sym(const char *str, const char *end, char *buf, int maxlen, int mode)
> +{
> +	int rlen = 0;
> +	int array = 0;
> +	int narg = 0;
> +	const char *q;
> +
> +	if (!end)
> +		end = str + strlen(str);
> +
> +	for (q = str; q != end; q++) {
> +
> +		if (rlen == (maxlen - 1))
> +			break;
> +
> +		switch (*q) {
> +		case 'L':
> +			if (mode == MODE_PREFIX || mode == MODE_CTYPE) {
> +				if (mode == MODE_CTYPE) {
> +					if (narg)
> +						rlen += snprintf(buf+rlen, maxlen - rlen, ", ");
> +					narg++;
> +				}
> +				rlen += snprintf(buf+rlen, maxlen - rlen, "class ");

I think you should replace all these snprintf with scnprintf to avoid
that trap described in its man page:

-----
Return value:

       The functions snprintf() and vsnprintf() do not write more than
size bytes (including the terminating null byte ('\0')).  If the output
was truncated due to this limit then  the  return  value  is  the number
of  characters (excluding  the  terminating  null  byte) which would
have been written to the final string if enough space had been
available.  Thus, a return value of size or more means that the output
was truncated.  (See also below under NOTES.)
-----

I.e. it will not return the number of bytes _printed_, which is what you
expect, no? I.e. you don't seem to be checking for truncation.

Nit:

please have spaces separating operators consistently, i.e.  sometimes
you use 'a+b', sometimes 'a + b', please use consistently 'a + b'.

- Arnaldo


> +				if (mode == MODE_PREFIX)
> +					mode = MODE_CLASS;
> +			} else
> +				buf[rlen++] = *q;
> +			break;
> +		case 'B':
> +		case 'C':
> +		case 'D':
> +		case 'F':
> +		case 'I':
> +		case 'J':
> +		case 'S':
> +		case 'Z':
> +			if (mode == MODE_TYPE) {
> +				if (narg)
> +					rlen += snprintf(buf+rlen, maxlen - rlen, ", ");
> +				rlen += snprintf(buf+rlen, maxlen - rlen, "%s", base_types[*q - 'A']);
> +				while(array--)
> +					rlen += snprintf(buf+rlen, maxlen - rlen, "[]");
> +				array = 0;
> +				narg++;
> +			} else
> +				buf[rlen++] = *q;
> +			break;
> +		case 'V':
> +			if (mode == MODE_TYPE) {
> +				rlen += snprintf(buf+rlen, maxlen - rlen, "void");
> +				while(array--)
> +					rlen += snprintf(buf+rlen, maxlen - rlen, "[]");
> +				array = 0;
> +			} else
> +				buf[rlen++] = *q;
> +			break;
> +		case '[':
> +			if (mode != MODE_TYPE)
> +				goto error;
> +			array++;
> +			break;
> +		case '(':
> +			if (mode != MODE_FUNC)
> +				goto error;
> +			buf[rlen++] = *q;
> +			mode = MODE_TYPE;
> +			break;
> +		case ')':
> +			if (mode != MODE_TYPE)
> +				goto error;
> +			buf[rlen++] = *q;
> +			narg = 0;
> +			break;
> +		case ';':
> +			if (mode != MODE_CLASS && mode != MODE_CTYPE)
> +				goto error;
> +			/* safe because at least one other char to process */
> +			if (isalpha(*(q+1)))
> +				rlen += snprintf(buf+rlen, maxlen - rlen, ".");
> +			if (mode == MODE_CLASS)
> +				mode = MODE_FUNC;
> +			else if (mode == MODE_CTYPE)
> +				mode = MODE_TYPE;
> +			break;
> +		case '/':
> +			if (mode != MODE_CLASS && mode != MODE_CTYPE)
> +				goto error;
> +			rlen += snprintf(buf+rlen, maxlen - rlen, ".");
> +			break;
> +		default :
> +			buf[rlen++] = *q;
> +		}
> +	}
> +	buf[rlen] = '\0';
> +	return buf;
> +error:
> +	return NULL;
> +}
> +
> +/*
> + * Demangle Java function signature (openJDK, not GCJ)
> + * input:
> + * 	str: string to parse. String is not modified
> + *    flags: comobination of JAVA_DEMANGLE_* flags to modify demangling
> + * return:
> + *	if input can be demangled, then a newly allocated string is returned.
> + *	if input cannot be demangled, then NULL is returned
> + *
> + * Note: caller is responsible for freeing demangled string
> + */
> +char *
> +java_demangle_sym(const char *str, int flags)
> +{
> +	char *buf, *ptr;
> +	char *p;
> +	size_t len, l1 = 0;
> +
> +	if (!str)
> +		return NULL;
> +
> +	/* find start of retunr type */
> +	p = strrchr(str, ')');
> +	if (!p)
> +		return NULL;
> +
> +	/*
> +	 * expansion factor estimated to 3x
> +	 */
> +	len = strlen(str) * 3 + 1;
> +	buf = malloc(len);
> +	if (!buf)
> +		return NULL;
> +
> +	buf[0] = '\0';
> +	if (!(flags & JAVA_DEMANGLE_NORET)) {
> +		/*
> +		 * get return type first
> +		 */
> +		ptr = __demangle_java_sym(p+1, NULL, buf, len, MODE_TYPE);
> +		if (!ptr)
> +			goto error;
> +
> +		/* add space between return type and function prototype */
> +		l1 = strlen(buf);
> +		buf[l1++] = ' ';
> +	}
> +
> +	/* process function up to return type */
> +	ptr = __demangle_java_sym(str, p + 1, buf + l1, len - l1, MODE_PREFIX);
> +	if (!ptr)
> +		goto error;
> +
> +	return buf;
> +error:
> +	free(buf);
> +	return NULL;
> +}
> diff --git a/tools/perf/util/demangle-java.h b/tools/perf/util/demangle-java.h
> new file mode 100644
> index 0000000..a981c1f
> --- /dev/null
> +++ b/tools/perf/util/demangle-java.h
> @@ -0,0 +1,10 @@
> +#ifndef __PERF_DEMANGLE_JAVA
> +#define __PERF_DEMANGLE_JAVA 1
> +/*
> + * demangle function flags
> + */
> +#define JAVA_DEMANGLE_NORET	0x1 /* do not process return type */
> +
> +char * java_demangle_sym(const char *str, int flags);
> +
> +#endif /* __PERF_DEMANGLE_JAVA */
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index 476268c..2174bf4 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -6,6 +6,7 @@
>  #include <inttypes.h>
>  
>  #include "symbol.h"
> +#include "demangle-java.h"
>  #include "machine.h"
>  #include "vdso.h"
>  #include <symbol/kallsyms.h>
> @@ -1046,6 +1047,8 @@ int dso__load_sym(struct dso *dso, struct map *map,
>  				demangle_flags = DMGL_PARAMS | DMGL_ANSI;
>  
>  			demangled = bfd_demangle(NULL, elf_name, demangle_flags);
> +			if (demangled == NULL)
> +				demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET);
>  			if (demangled != NULL)
>  				elf_name = demangled;
>  		}
> -- 
> 1.9.1

  parent reply	other threads:[~2015-03-25 22:19 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-24 22:25 [PATCH v4 0/4] perf: add support for profiling jitted code Stephane Eranian
2015-03-24 22:25 ` [PATCH v4 1/4] perf: Use monotonic clock as a source for timestamps Stephane Eranian
2015-03-24 22:25 ` [PATCH v4 2/4] perf tools: add Java demangling support Stephane Eranian
2015-03-25 20:34   ` Carl E. Love
2015-03-26  0:57     ` Stephane Eranian
2015-03-26  1:03       ` David Ahern
2015-03-25 22:18   ` Arnaldo Carvalho de Melo [this message]
2015-03-24 22:25 ` [PATCH v4 3/4] perf inject: add jitdump mmap injection support Stephane Eranian
2015-03-25 20:41   ` Carl E. Love
2015-03-25 22:15     ` David Ahern
2015-03-25 21:17   ` Carl E. Love
2015-03-26  8:00   ` Adrian Hunter
2015-03-24 22:25 ` [PATCH v4 4/4] perf tools: add JVMTI agent library Stephane Eranian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150325221845.GC2161@redhat.com \
    --to=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=ak@linux.intel.com \
    --cc=cel@us.ibm.com \
    --cc=dsahern@gmail.com \
    --cc=eranian@google.com \
    --cc=johnmccutchan@google.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=namhyung@kernel.org \
    --cc=pawel.moll@arm.com \
    --cc=peterz@infradead.org \
    --cc=sonnyrao@chromium.org \
    --cc=sukadev@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).