vfork/setjmp workarounds
by Jiri Olsa
hi,
I finally got the gdb running... haleluya :)
you can try vfork-setjmp branch in
git://fedorapeople.org/home/fedora/jolsa/public_git/latrace.git
the fix is probably just temporary, since I'm not sure there's
better way to fix it directly in glibc
I'll keep you posted... I'm attaching the description of the issues,
any ideas are welcome ;)
once I run of ideas, I'll make a glibc BZ and unleash some anger ;)
wbr,
jirka
----------------------------------------------------------------------
setjmp calls family:
This is caused by the runtime linker to call the pltexit handler.
In this case:
- the 'framesize' portion of stack is copied on top of the
current stack
- setjmp is called over the new stack
- pltexit handler is called
The setjmp function works by storing environment and return IP
to the jmp_buf buffer. The longjmp afterwards reads the jmp_buf
and jumps to its return IP.
The point is that setjmp gets the return IP in the stack via:
movq (%rsp), %rax /* Save PC we are returning to now. */
So if it is called from the pltexit handler path,
it will get wrong return IP, since it does not expect LD_AUDIT stuff
on the stack..
this might be probably fixed within the setjmp function itself,
to check if the auditing is active... I'm looking on that ;)
----------------------------------------------------------------------
vfork:
there're 2 main thing about vfork:
- once vfork is called the parrent is stoped and child continues.
- both parent and child share the same address space
So whatever function called right after the vfork call within
the child path, will mess the return vfork address for the parent.
And again only in the pltexit path, since it's using stack for storing
return values.
I'm not sure this could be fixed in glibc..
13 years, 5 months
Re: [PATCH] Add '-n' option, allowing to skip tracing certain symbols
by Jiri Olsa
On Wed, Oct 13, 2010 at 9:39 PM, Artur Skawina <art.08.09(a)gmail.com> wrote:
> Wanted to use latrace on an app that was using setjmp/longjmp;
> and to avoid latrace causing a crash had to use the patch below.
>
> "latrace -Ap -n setjmp ..." was enough to make things work.
hi,
I was just working on a glibc fix for auditing vfork and sig/setjmp functions ;)
this is good workaround
>
> While doing this noticed the LA_SYMB_NOPLTEXIT omission for
> the '-s syms' case; not knowing if that was intentional i did
> not change that.
yea, I probably overlooked that.. however I checked glibc source and once
you return LA_SYMB_NOPLTENTER, pltexit is never called anyway.. but
I added it just in case glibc will fix this in the future.. thanks for noticing
it's nice to see someone is actually using this ;) thanks
jirka
ps ccing latrace list
>
> artur
>
>
> From: Artur Skawina <art.08.09(a)gmail.com>
> Date: Wed, 13 Oct 2010 18:42:57 +0000
> Subject: [PATCH] Add '-n' option, allowing to skip tracing certain symbols
>
> Makes it possible omit tracing just some calls, like 'setjmp'.
> ---
> doc/latrace.txt | 5 ++++-
> src/audit-init.c | 7 +++++++
> src/audit.c | 5 +++++
> src/config.c | 11 ++++++++++-
> src/config.h | 4 ++++
> 5 files changed, 30 insertions(+), 2 deletions(-)
>
> diff --git a/doc/latrace.txt b/doc/latrace.txt
> index b24742a..ab2044d 100644
> --- a/doc/latrace.txt
> +++ b/doc/latrace.txt
> @@ -10,7 +10,7 @@ latrace - LD_AUDIT 2.4+ libc frontend
>
> SYNOPSIS
> --------
> -*latrace* [-ltfsbcCpADaoyIiBdvTFELVh] command [arg ... ]
> +*latrace* [-ltfsnbcCpADaoyIiBdvTFELVh] command [arg ... ]
>
>
> DESCRIPTION
> @@ -45,6 +45,9 @@ OPTIONS
> *-s, --sym sym1[,sym2,...]*::
> audit symbols sym1, sym2 ...
>
> +*-n, --omit-sym sym1[,sym2,...]*::
> + omit symbols sym1, sym2 ...
> +
> *-S, --timestamp*::
> display timestamp for each symbol
>
> diff --git a/src/audit-init.c b/src/audit-init.c
> index 81ab1e5..322efe0 100644
> --- a/src/audit-init.c
> +++ b/src/audit-init.c
> @@ -189,6 +189,13 @@ int audit_init(int argc, char **argv, char **env)
> return -1;
> }
>
> + /* -n */
> + if ((*lt_sh(&cfg, skipsymbols)) &&
> + (-1 == (cfg.skipsymbols_cnt = get_names(&cfg, lt_sh(&cfg, skipsymbols), cfg.skipsymbols)))) {
> + printf("latrace failed to parse symbols to omit\n");
> + return -1;
> + }
> +
> /* -b */
> if ((*lt_sh(&cfg, flow_below)) &&
> (-1 == (cfg.flow_below_cnt = get_names(&cfg, lt_sh(&cfg, flow_below), cfg.flow_below)))) {
> diff --git a/src/audit.c b/src/audit.c
> index 2a97b75..2494d93 100644
> --- a/src/audit.c
> +++ b/src/audit.c
> @@ -234,6 +234,11 @@ static unsigned int la_symbind(const char *symname)
> flags = 0;
> }
>
> + if (cfg.skipsymbols_cnt) {
> + if (check_names((char*) symname, cfg.skipsymbols))
> + flags = LA_SYMB_NOPLTENTER|LA_SYMB_NOPLTEXIT;
> + }
> +
> return flags;
> }
>
> diff --git a/src/config.c b/src/config.c
> index 3f3145c..ba222d3 100644
> --- a/src/config.c
> +++ b/src/config.c
> @@ -34,6 +34,7 @@ static void usage()
> printf(" -t, --libs-to lib1,lib2... audit to lib1, lib2 ...\n");
> printf(" -f, --libs-from lib1,lib2... audit from lib1, lib2 ...\n");
> printf(" -s, --sym sym1,sym2... audit symbols sym1, sym2 ... \n");
> + printf(" -n, --omit-sym sym1,sym2... omit symbols sym1, sym2 ... \n");
> printf(" -L, --lib-subst s1,s2... objsearch LD_AUDIT interface (see man page)\n");
> printf("\n");
> printf(" -c, --counts display statistics counts of symbols\n");
> @@ -127,6 +128,7 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
> int option_index = 0;
> static struct option long_options[] = {
> {"sym", required_argument, 0, 's'},
> + {"omit-sym", required_argument, 0, 'n'},
> {"libs", required_argument, 0, 'l'},
> {"libs-to", required_argument, 0, 't'},
> {"libs-from", required_argument, 0, 'f'},
> @@ -157,7 +159,7 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
> {0, 0, 0, 0}
> };
>
> - c = getopt_long(argc, argv, "+s:l:t:f:vhi:BdISb:cC:y:YL:po:a:ADVTFERq",
> + c = getopt_long(argc, argv, "+s:n:l:t:f:vhi:BdISb:cC:y:YL:po:a:ADVTFERq",
> long_options, &option_index);
>
> if (c == -1)
> @@ -192,6 +194,13 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
> strncpy(lt_sh(cfg, symbols), optarg, strlen(optarg));
> break;
>
> + case 'n':
> + if (strlen(optarg) > LT_SYMBOLS_MAXSIZE)
> + return -1;
> +
> + strncpy(lt_sh(cfg, skipsymbols), optarg, strlen(optarg));
> + break;
> +
> case 'b':
> if (strlen(optarg) > LT_SYMBOLS_MAXSIZE)
> return -1;
> diff --git a/src/config.h b/src/config.h
> index 2a36c58..71f319a 100644
> --- a/src/config.h
> +++ b/src/config.h
> @@ -84,6 +84,7 @@ struct lt_config_shared {
>
> #define LT_SYMBOLS_MAXSIZE 200
> char symbols[LT_SYMBOLS_MAXSIZE];
> + char skipsymbols[LT_SYMBOLS_MAXSIZE];
>
> char flow_below[LT_SYMBOLS_MAXSIZE];
>
> @@ -186,6 +187,9 @@ struct lt_config_audit {
> char *symbols[LT_NAMES_MAX];
> int symbols_cnt;
>
> + char *skipsymbols[LT_NAMES_MAX];
> + int skipsymbols_cnt;
> +
> char *flow_below[LT_NAMES_MAX];
> int flow_below_cnt;
>
> --
>
13 years, 5 months
make clean
by Akos PASZTORY
Hi,
maybe it would a good idea to change make clean to do something more
gentle than "git clean -dxf". It's quite easy to lose some code you
are working on and just put it into the source directory...
--
akos
13 years, 5 months