[Ltrace-devel] Some patches for ltrace
Andrey Zonov
zont at FreeBSD.org
Mon Aug 27 11:58:41 UTC 2012
On 8/27/12 1:30 PM, Petr Machata wrote:
> Andrey Zonov <zont at FreeBSD.org> writes:
>
>> I'm now porting ltrace on FreeBSD amd64 [1] and found a few bugs.
>> Please look at the following commits:
>
> Thank you. Next time around, would you please be so kind as to post
> each of those as a patch, like what git-format-patch does? This would
> allow me to review in e-mail, and eventually apply them.
Sure, but I thought that the merge from my tree is easier way to apply them.
>
> You commit messages start with dashes. Our don't. The first line of a
> commit message acts similarly to Subject: in e-mail messages.
AFAIK, you can change commit message as you want.
>
> Apart from the particular commits that you point out. Most of the
> FreeBSD code is very similar to Linux code. This is guaranteed to
> bitrot. Either FreeBSD will see fixes that would be useful for Linux,
> or the other way around. It seems like the job control parts should be
> fairly similar among these two OS's, and it should be possible to reuse
> this and only call back to OS hooks for the low-level work.
The thread implementation is strongly different in FreeBSD, that is the
main problem of the port.
>
> Also note that I intended to merge pmachata/abi branch for some time
> now. I don't think it collides with your work, but it does touch a lot
> of ltrace core, and might introduce bugs that you will see on FreeBSD as
> well. I'll try to get around to the merge really soon now.
>
Where can I find this branch to try it?
>> a2d199eda1f0e6dd5e3dc38fdef9383dca602993
>
> I don't understand the problem. When does it break and how? Leaking
> memory is certainly less bad than crashing, but we would prefer fixing
> the underlying bug.
This is a using memory after free(3). I found it, because "FreeBSD
current" uses memory allocator that trashes memory after free(3) and
ltrace got SIGSEGV.
You can easily reproduce that problem with valgrind under Linux. Test
program is attached.
$ valgrind ./ltrace -f ./run 1 /bin/sleep 1
...
==18947== Invalid read of size 8
==18947== at 0x40C634: breakpoint_name (breakpoints.c:274)
==18947== by 0x40BD3B: disable_breakpoint (breakpoint.c:109)
==18947== by 0x40BAE4: disable_and (trace.c:709)
==18947== by 0x40B7A5: process_stopping_on_event (trace.c:772)
==18947== by 0x40B9C3: process_install_stopping_handler (trace.c:919)
==18947== by 0x40BA59: continue_after_breakpoint (trace.c:940)
==18947== by 0x4114AC: handle_event (handle_event.c:651)
==18947== by 0x402FCD: ltrace_main (libltrace.c:164)
==18947== by 0x402F3D: main (main.c:35)
==18947== Address 0x5b7c290 is 16 bytes inside a block of size 40 free'd
==18947== at 0x4C270BD: free (vg_replace_malloc.c:366)
==18947== by 0x407C6A: library_destroy (library.c:275)
==18947== by 0x405B6B: private_process_destroy (proc.c:159)
==18947== by 0x405BDA: process_destroy (proc.c:176)
==18947== by 0x405C53: remove_process (proc.c:562)
==18947== by 0x411958: handle_event (handle_event.c:437)
==18947== by 0x402FCD: ltrace_main (libltrace.c:164)
==18947== by 0x402F3D: main (main.c:35)
...
Without valgrind you can see sometimes "null" function name:
[pid 24498] (null)(0x400940, 0, 0x76a88f48cd027e, -1, 0)
= 10
[pid 24498] (null)(0x7fff632ebdd8, 0x7fff632eb568, 0, 0x7fff632eb568,
0xffffffff <no return ...>
>
>> 22a1b7e90b2a0727ff08fc7224e9a897541ad3cd
>> 82a518c836af43592e8f3d3d830902a6500f8f80
>> ebd3e4c7e68065f1829ca84d7830c583efc12cff
>
> Why is this needed?
Also using after free(3).
...
== Invalid read of size 4
==18947== at 0x40B6A6: process_stopping_on_event (trace.c:381)
==18947== by 0x41120C: handle_event (handle_event.c:66)
==18947== by 0x402FCD: ltrace_main (libltrace.c:164)
==18947== by 0x402F3D: main (main.c:35)
==18947== Address 0x5b81c0c is 76 bytes inside a block of size 104 free'd
==18947== at 0x4C270BD: free (vg_replace_malloc.c:366)
==18947== by 0x405949: destroy_event_handler (proc.c:582)
==18947== by 0x40B6A5: process_stopping_on_event (trace.c:377)
==18947== by 0x41120C: handle_event (handle_event.c:66)
==18947== by 0x402FCD: ltrace_main (libltrace.c:164)
==18947== by 0x402F3D: main (main.c:35)
==18947==
==18947== Invalid read of size 8
==18947== at 0x40B6B0: process_stopping_on_event (trace.c:386)
==18947== by 0x41120C: handle_event (handle_event.c:66)
==18947== by 0x402FCD: ltrace_main (libltrace.c:164)
==18947== by 0x402F3D: main (main.c:35)
==18947== Address 0x5b81c00 is 64 bytes inside a block of size 104 free'd
==18947== at 0x4C270BD: free (vg_replace_malloc.c:366)
==18947== by 0x405949: destroy_event_handler (proc.c:582)
==18947== by 0x40B6A5: process_stopping_on_event (trace.c:377)
==18947== by 0x41120C: handle_event (handle_event.c:66)
==18947== by 0x402FCD: ltrace_main (libltrace.c:164)
==18947== by 0x402F3D: main (main.c:35)
...
>
>> 9efa0a117c5f00e47ae1f0b6f64a3d7b561cd9b8
>> ee55fecf97ebd7a9ec481a9629389eacf69be3d3
>> 3558a13d3b8b43fd0e977128bc7b6a75ae3537a0
>> 6a1eb194f36d008e5d254447645e06be7baf53ff
>>
>> [1] https://github.com/z0nt/ltrace
>
> Thank you,
> PM
>
--
Andrey Zonov
-------------- next part --------------
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
int need_fork;
if (argc < 3)
errx(1, "usage: <fork> <arg1> [arg2] ...");
need_fork = atoi(argv[1]);
if (need_fork) {
if (fork() == 0) {
printf("from CHILD");
argv += 2;
execve(argv[0], argv, NULL);
err(1, "execve");
} else {
if (need_fork == 2)
waitpid(-1, NULL, 0);
return (0);
}
} else {
argv += 2;
execve(argv[0], argv, NULL);
err(1, "execve");
}
exit(0);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 535 bytes
Desc: OpenPGP digital signature
URL: <http://lists.alioth.debian.org/pipermail/ltrace-devel/attachments/20120827/5b9f3594/attachment.pgp>
More information about the Ltrace-devel
mailing list