* Re: [PATCH] Use mmap for symbol tables
@ 2006-01-31 4:53 David Anderson
0 siblings, 0 replies; 31+ messages in thread
From: David Anderson @ 2006-01-31 4:53 UTC (permalink / raw)
To: eirik, jimb; +Cc: gdb-patches
Eirik Fuller <eirik@hackrat.com>
> I've already mentioned that the wasted address space isn't all that big,
> at least not in the symbol tables I'm accustomed to. Anyone who is
> crowding the limits of virtual address space will run out soon enough
The size of the text and the data can be very large indeed.
And those, as mmap, are not going to be used normally.
So are wasted virtual address space in the debugger.
If gdb runs out of space building what it needs that's one thing.
But running out because gdb is wasting space is another thing
entirely -- best not to go there.
Again, this is a 'been there done that' comment and
is, I hope, not a waste of everyone's time (or worse).
David Anderson
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
@ 2006-01-31 4:40 David Anderson
2006-01-31 5:00 ` Eirik Fuller
` (2 more replies)
0 siblings, 3 replies; 31+ messages in thread
From: David Anderson @ 2006-01-31 4:40 UTC (permalink / raw)
To: gdb-patches; +Cc: jimb, eirik
Jim Blandy
> I understand that it would make your BFD code more complicated, but it
> seems to me you want to map individual sections, not entire files.
> Again, this will still share memory with the block cache, so aside
> from the complexity I don't see the downside.
Eirik Fuller
>I don't see the upside of making the code more complicated. The
>downside of the extra complication is that it makes the patch less
>likely to the point of never actually existing. :-)
>
>Could you be more specific about why multiple mmap regions per file are
>preferable? (It might help to keep in mind that I'm using PROT_READ and
>MAP_SHARED). The only downside I can see is the (relatively small)
>fraction of each symbol table which is not accessed via mmap, but that
>doesn't use memory, just virtual address space (if it does use memory,
>that contradicts the "not accessed" part).
Hope the following is not out of line.
The phrase 'just virtual address space' should not, IMO, be
uttered so cavalierly. Mapping in one glob will in some cases
make gdb useless for some apps (fearless prediction).
Been there, done that, with IRIX/dbx and 'just virtual address
space' was a disaster for a few big apps with large value to
the owners/users (when the apps needed debugging). Meaning we
did exactly what Eirik Fuller proposes and had to drop back to
exactly what Jim Blandy proposes. [The problem was with 32 bit
address space of the debugger as it existed a few years ago.]
And don't mmap in a whole core file for the same reason (not
that such is being proposed, this is just another thought).
David Anderson
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH] Use mmap for symbol tables
2006-01-31 4:40 David Anderson
@ 2006-01-31 5:00 ` Eirik Fuller
2006-01-31 5:34 ` Jim Blandy
2006-01-31 17:45 ` David Anderson
2006-01-31 18:24 ` Jim Blandy
2 siblings, 1 reply; 31+ messages in thread
From: Eirik Fuller @ 2006-01-31 5:00 UTC (permalink / raw)
To: David Anderson; +Cc: gdb-patches, Jim Blandy
> Been there, done that, with IRIX/dbx and 'just virtual address
> space' was a disaster for a few big apps
I don't know how dbx handles symbol tables, but in my experience the
size of a symbol table needs to be within a particular power of two to
exhaust virtual address space in a situation where gdb won't exhaust it
anyway with malloc. A debugger which only keeps a small subset of a
symbol table resident in memory (whether it uses malloc or mmap) can
obviously handle much larger symbol tables, but in my experience that
doesn't describe gdb.
If the mmap patch is runtime optional and disabled by default, it won't
make corner cases with large symbol tables any worse. I believe the
right long term answer is a better symbol table format (with indexing
stored on disk), even on 64 bit hosts.
> The size of the text and the data can be very large indeed.
> And those, as mmap, are not going to be used normally.
> So are wasted virtual address space in the debugger.
This suggests a simple way to complicate my mmap patch. If it can be
determined beforehand what interval of the symbol table gdb is going to
read in its entirety, that interval can be recorded in the BFD struct,
and the first mmap call can map just that interval. That will
complicate the offset calculations somewhat, but the basic approach will
be the same. This will only waste virtual address space if the sections
gdb would otherwise read don't form a contiguous region of the file.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 5:00 ` Eirik Fuller
@ 2006-01-31 5:34 ` Jim Blandy
2006-01-31 14:00 ` Daniel Jacobowitz
0 siblings, 1 reply; 31+ messages in thread
From: Jim Blandy @ 2006-01-31 5:34 UTC (permalink / raw)
To: Eirik Fuller; +Cc: David Anderson, gdb-patches
On 1/30/06, Eirik Fuller <eirik@hackrat.com> wrote:
> This suggests a simple way to complicate my mmap patch. If it can be
> determined beforehand what interval of the symbol table gdb is going to
> read in its entirety, that interval can be recorded in the BFD struct,
> and the first mmap call can map just that interval. That will
> complicate the offset calculations somewhat, but the basic approach will
> be the same. This will only waste virtual address space if the sections
> gdb would otherwise read don't form a contiguous region of the file.
Actually, that's a pretty great idea. We could have the linker
arrange to put all the debug sections together; that's easy. Then we
could have the BFD API let GDB specify a list of sections to map. BFD
would map the smallest contiguous region containing those sections.
You'd get an interface that works with all files, but performs better
when the linker does its job right.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 5:34 ` Jim Blandy
@ 2006-01-31 14:00 ` Daniel Jacobowitz
2006-01-31 18:39 ` Jim Blandy
0 siblings, 1 reply; 31+ messages in thread
From: Daniel Jacobowitz @ 2006-01-31 14:00 UTC (permalink / raw)
To: Jim Blandy; +Cc: Eirik Fuller, David Anderson, gdb-patches
On Mon, Jan 30, 2006 at 09:34:38PM -0800, Jim Blandy wrote:
> On 1/30/06, Eirik Fuller <eirik@hackrat.com> wrote:
> > This suggests a simple way to complicate my mmap patch. If it can be
> > determined beforehand what interval of the symbol table gdb is going to
> > read in its entirety, that interval can be recorded in the BFD struct,
> > and the first mmap call can map just that interval. That will
> > complicate the offset calculations somewhat, but the basic approach will
> > be the same. This will only waste virtual address space if the sections
> > gdb would otherwise read don't form a contiguous region of the file.
>
> Actually, that's a pretty great idea. We could have the linker
> arrange to put all the debug sections together; that's easy. Then we
> could have the BFD API let GDB specify a list of sections to map. BFD
> would map the smallest contiguous region containing those sections.
> You'd get an interface that works with all files, but performs better
> when the linker does its job right.
... why? You're jumping through hoops here to avoid mmaping each
individual section, but I don't understand what's wrong with that.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 14:00 ` Daniel Jacobowitz
@ 2006-01-31 18:39 ` Jim Blandy
2006-02-01 18:11 ` Eirik Fuller
0 siblings, 1 reply; 31+ messages in thread
From: Jim Blandy @ 2006-01-31 18:39 UTC (permalink / raw)
To: Jim Blandy, Eirik Fuller, David Anderson, gdb-patches
On 1/31/06, Daniel Jacobowitz <drow@false.org> wrote:
> On Mon, Jan 30, 2006 at 09:34:38PM -0800, Jim Blandy wrote:
> > On 1/30/06, Eirik Fuller <eirik@hackrat.com> wrote:
> > > This suggests a simple way to complicate my mmap patch. If it can be
> > > determined beforehand what interval of the symbol table gdb is going to
> > > read in its entirety, that interval can be recorded in the BFD struct,
> > > and the first mmap call can map just that interval. That will
> > > complicate the offset calculations somewhat, but the basic approach will
> > > be the same. This will only waste virtual address space if the sections
> > > gdb would otherwise read don't form a contiguous region of the file.
> >
> > Actually, that's a pretty great idea. We could have the linker
> > arrange to put all the debug sections together; that's easy. Then we
> > could have the BFD API let GDB specify a list of sections to map. BFD
> > would map the smallest contiguous region containing those sections.
> > You'd get an interface that works with all files, but performs better
> > when the linker does its job right.
>
> ... why? You're jumping through hoops here to avoid mmaping each
> individual section, but I don't understand what's wrong with that.
Sorry, "great idea" meant "clever way of satisfying the constraints
Eirik has set"; I suggested mapping individual sections at the front,
but Eirik said he wasn't interested in implementing that. "Great
idea" didn't mean "this is the Way It Should Be Done." I was caught
up in the moment.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 18:39 ` Jim Blandy
@ 2006-02-01 18:11 ` Eirik Fuller
0 siblings, 0 replies; 31+ messages in thread
From: Eirik Fuller @ 2006-02-01 18:11 UTC (permalink / raw)
To: Jim Blandy; +Cc: David Anderson, gdb-patches
> Sorry, "great idea" meant "clever way of satisfying the constraints
> Eirik has set";
I thought "great idea" seemed a bit over the top when I first read it;
"nifty hack" might be a bit closer. :-)
> I suggested mapping individual sections at the front, but Eirik said
> he wasn't interested in implementing that.
I'm not sure I put it that strongly. I certainly haven't implemented it
yet, because I prefer the simplest approach which works. Given a choice
between a simple patch which works well for my problem space and doing
without because I don't have the energy to complicate things enough to
avoid wasting some virtual address space (a minor amount really, in the
particular context I was operating in), the simple patch won.
This discussion has also included the more general issue of whether
using mmap is the right answer in the first place. If the answer to
that more fundamental question is no, the other details really don't
much matter. :-)
I think I've already convinced myself (with much appreciated help from
this thread) that making mmap the default way of reading symbol tables
in GDB is probably not the right answer. I would even go so far as to
say I'm not convinced there are enough people who can benefit from it to
make it a standard part of GDB (although I haven't given up on that
yet). But if nothing else, posting my patch at least gives others in
similar situations (huge symbol tables which "never" disappear with a
strong likelihood of multiple concurrent GDB sessions on the same symbol
table) an alternative to filling up their swap space. Perhaps the best
argument in favor of including this in the distribution, in some fashion
(with or without the extra complication to conserve address space),
disabled by default, is that not everyone who might benefit from this
approach pays attention to this mailing list.
If it would substantially improve the chances of including mmap support
(optional at both compile time and runtime) in the GDB distribution, I'd
be willing to take a crack at adding the complication to mmap only stuff
that GDB reads anyway. And either way I still need to look at the
symfile_relocate_debug_section question, and fill in the gaps (the
configure hooks and documentation and test cases). Plus I intend to
perform more timing experiments (including symbol tables on local disk).
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 4:40 David Anderson
2006-01-31 5:00 ` Eirik Fuller
@ 2006-01-31 17:45 ` David Anderson
2006-01-31 18:24 ` Jim Blandy
2 siblings, 0 replies; 31+ messages in thread
From: David Anderson @ 2006-01-31 17:45 UTC (permalink / raw)
To: David Anderson, Eirik Fuller; +Cc: Jim Blandy, gdb-patches
|> Been there, done that, with IRIX/dbx and 'just virtual address
|> space' was a disaster for a few big apps
|
|I don't know how dbx handles symbol tables, but in my experience the
|size of a symbol table needs to be within a particular power of two to
|exhaust virtual address space in a situation where gdb won't exhaust it
|anyway with malloc. A debugger which only keeps a small subset of a
|symbol table resident in memory (whether it uses malloc or mmap) can
|obviously handle much larger symbol tables, but in my experience that
|doesn't describe gdb.
The problem was not symbol tables (which IRIX dbx does not
do as well as gdb!) but the 'gratuitous' mapping
in of the text and data space of the executable and
shared libraries -- just to get to symbol data.
We got away with it for a long time, but people do press
the boundaries and eventually we had to redo it.
What with memory so cheap and cpus so fast these days
more and more apps press these boundaries.
>This suggests a simple way to complicate my mmap patch. If it can be
>determined beforehand what interval of the symbol table gdb is going to
>read in its entirety, that interval can be recorded in the BFD struct,
>and the first mmap call can map just that interval. That will
>complicate the offset calculations somewhat, but the basic approach will
>be the same. This will only waste virtual address space if the sections
>gdb would otherwise read don't form a contiguous region of the file.
An intriguing observation.
For most Elf files your 'simple way' will work, I think.
How often it won't is unclear...
Don't let my opinions discourage you, you are doing good work
whether or not it gets into gdb at this point.
David Anderson
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 4:40 David Anderson
2006-01-31 5:00 ` Eirik Fuller
2006-01-31 17:45 ` David Anderson
@ 2006-01-31 18:24 ` Jim Blandy
2 siblings, 0 replies; 31+ messages in thread
From: Jim Blandy @ 2006-01-31 18:24 UTC (permalink / raw)
To: David Anderson; +Cc: gdb-patches, eirik
On 1/30/06, David Anderson <davea@quasar.engr.sgi.com> wrote:
> Hope the following is not out of line.
No, not at all; it's great to get perspective from other implementers.
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH] Use mmap for symbol tables
@ 2006-01-29 23:36 Eirik Fuller
2006-01-30 5:04 ` Jim Blandy
` (2 more replies)
0 siblings, 3 replies; 31+ messages in thread
From: Eirik Fuller @ 2006-01-29 23:36 UTC (permalink / raw)
To: gdb-patches
I'm enclosing a patch which modifies gdb to use mmap instead of malloc
and seek and read. It's a rough cut, in a number of respects. I have
not written a ChangeLog entry or test case or documentation. I assume
there are other places in gdb that can use this, but I've only made
changes for a few of them (the biggest memory users for the symbol
table formats I use most). I have not provided a way to select this
at compile time, or test for features it requires at configure time.
The patch doesn't even indent the code properly, to make it a little
bit easier to see what's different.
My immediate goal is to solicit opinions on whether the basic approach
is sound. Comments in gdb/dwarf2read.c indicate the idea is not new.
I first started using an approach similar to what's in the enclosed
patch long before I noticed those comments; those comments finally
motivated me to dust this off.
This patch takes a very simple approach. It mmaps the entire symbol
table file the first time any caller tries to use the new function (I
am in no way loyal to the name bfd_fetch, but I think it's preferable
to, say, bfd_mmap in that it conveys the notion that a single mmap
call can lead to multiple accesses). It munmaps the file contents
only when its BFD is deleted.
If there's any drawback to the simple approach of mmaping the entire
file, it's that it uses more than bare minimum of virtual address
space. I haven't seen a symbol table big enough for that to matter.
For the symbol tables I use, most of that address space will be used
anyway (the symbol table data occupies far more than half of the file
size in the symbol tables I use), but it fits in the file system cache
rather than in swap space, and concurrent gdb processes on the same
symbol table can save considerable amounts of system memory.
If there's any one drawback to the general idea of using mmap, it's
that in some cases (like symbol tables over NFS) the file data can
become unavailable, if an NFS server goes down or the file disappears
(unlinked open files don't work reliably over NFS). I suspect those
same drawbacks can kick in even without mmap, if gdb needs to flesh
out partial symbols long after it first reads the symbol table. It
wouldn't be difficult to add code to make this behavior optional even
when it's compiled in, if that seems useful.
This patch has one interesting benefit; it papers over a memory leak
in elfxx-mips.c; the READ macro in _bfd_mips_elf_read_ecoff_info uses
bfd_malloc instead of, say, bfd_alloc or the obstack machinery.
Choosing another symbol table with the file command, or even just
unloading the current one, doesn't seem to release that memory. I can
investigate that leak further if that seems useful, but for my own
purposes it's easier to use mmap for the big allocations. It's
possible there are similar leaks for other symbol table formats, but I
haven't fully explored that question.
I'm open to suggestions about how to improve this patch, or how to
make its adoption more likely. I don't think I've done any copright
assignment paperwork for gdb. I discussed it with my manager years
ago, but I don't specifically remember anything coming of that. I
plan to fix that some day; perhaps this patch will help provide
impetus for that.
Here's the patch:
--- bfd/bfd-in2.h.orig 2006-01-18 13:07:48.000000000 -0800
+++ bfd/bfd-in2.h 2006-01-29 14:30:38.000000000 -0800
@@ -476,6 +476,7 @@
extern file_ptr bfd_tell (bfd *);
extern int bfd_flush (bfd *);
extern int bfd_stat (bfd *, struct stat *);
+extern void *bfd_fetch (file_ptr fp, bfd_size_type size, bfd *abfd);
/* Deprecated old routines. */
#if __GNUC__
@@ -4270,6 +4271,9 @@
BFD_SEND (obfd, _bfd_copy_private_symbol_data, \
(ibfd, isymbol, obfd, osymbol))
+#include <unistd.h>
+#include <sys/mman.h>
+
/* Extracted from bfd.c. */
struct bfd
{
@@ -4435,6 +4439,10 @@
struct objalloc *, but we use void * to avoid requiring the inclusion
of objalloc.h. */
void *memory;
+ struct {
+ void *contents;
+ size_t length;
+ } mmap;
};
typedef enum bfd_error
--- bfd/opncls.c.orig 2005-11-03 08:06:11.000000000 -0800
+++ bfd/opncls.c 2006-01-29 14:39:22.000000000 -0800
@@ -117,6 +117,10 @@
{
bfd_hash_table_free (&abfd->section_htab);
objalloc_free ((struct objalloc *) abfd->memory);
+
+ if (abfd->mmap.contents)
+ munmap(abfd->mmap.contents, abfd->mmap.length);
+
free (abfd);
}
@@ -301,6 +305,30 @@
return bfd_fopen (filename, target, mode, fd);
}
+void *
+bfd_fetch (file_ptr fp, bfd_size_type size, bfd* abfd)
+{
+ if (!abfd->mmap.contents)
+ {
+ struct stat buf;
+ int fd = open(abfd->filename, O_RDONLY);
+ void *map;
+ size_t length;
+ fstat(fd, &buf);
+ length = buf.st_size;
+ map = mmap(0, length, PROT_READ, MAP_SHARED, fd, 0);
+ if (map && map != (void *) -1) {
+ abfd->mmap.length = length;
+ abfd->mmap.contents = map;
+ }
+ close(fd);
+ }
+ if (abfd->mmap.contents && abfd->mmap.length >= fp + size)
+ return abfd->mmap.contents + fp;
+ else
+ return NULL;
+}
+
/*
FUNCTION
bfd_openstreamr
--- bfd/ecoff.c.orig 2005-12-26 19:06:27.000000000 -0800
+++ bfd/ecoff.c 2006-01-29 12:44:16.000000000 -0800
@@ -556,18 +556,23 @@
ecoff_data (abfd)->sym_filepos = 0;
return TRUE;
}
+ pos = ecoff_data (abfd)->sym_filepos;
+ pos += backend->debug_swap.external_hdr_size;
+
+ raw = bfd_fetch(pos, raw_size, abfd);
+
+ if (!raw) {
raw = bfd_alloc (abfd, raw_size);
if (raw == NULL)
return FALSE;
- pos = ecoff_data (abfd)->sym_filepos;
- pos += backend->debug_swap.external_hdr_size;
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bread (raw, raw_size, abfd) != raw_size)
{
bfd_release (abfd, raw);
return FALSE;
}
+ }
ecoff_data (abfd)->raw_syments = raw;
--- bfd/elfxx-mips.c.orig 2005-12-30 21:02:22.000000000 -0800
+++ bfd/elfxx-mips.c 2006-01-29 12:46:13.000000000 -0800
@@ -768,12 +768,15 @@
else \
{ \
bfd_size_type amt = (bfd_size_type) size * symhdr->count; \
+ debug->ptr = bfd_fetch (symhdr->offset, amt, abfd); \
+ if (debug->ptr == NULL) { \
debug->ptr = bfd_malloc (amt); \
if (debug->ptr == NULL) \
goto error_return; \
if (bfd_seek (abfd, symhdr->offset, SEEK_SET) != 0 \
|| bfd_bread (debug->ptr, amt, abfd) != amt) \
goto error_return; \
+ } \
}
READ (line, cbLineOffset, cbLine, sizeof (unsigned char), unsigned char *);
--- gdb/dbxread.c.orig 2005-12-17 14:33:59.000000000 -0800
+++ gdb/dbxread.c 2006-01-29 12:47:10.000000000 -0800
@@ -708,6 +708,11 @@
error (_("ridiculous string table size (%d bytes)."),
DBX_STRINGTAB_SIZE (objfile));
+ DBX_STRINGTAB (objfile) = bfd_fetch(STRING_TABLE_OFFSET,
+ DBX_STRINGTAB_SIZE (objfile),
+ sym_bfd);
+
+ if (!DBX_STRINGTAB (objfile)) {
DBX_STRINGTAB (objfile) =
(char *) obstack_alloc (&objfile->objfile_obstack,
DBX_STRINGTAB_SIZE (objfile));
@@ -723,6 +728,7 @@
sym_bfd);
if (val != DBX_STRINGTAB_SIZE (objfile))
perror_with_name (name);
+ }
}
}
}
--- gdb/dwarf2read.c.orig 2006-01-17 14:30:29.000000000 -0800
+++ gdb/dwarf2read.c 2006-01-29 13:14:11.000000000 -0800
@@ -4953,6 +4953,9 @@
if (size == 0)
return NULL;
+ buf = bfd_fetch(sectp->filepos, size, abfd);
+
+ if (!buf) {
buf = obstack_alloc (&objfile->objfile_obstack, size);
retbuf = symfile_relocate_debug_section (abfd, sectp, buf);
if (retbuf != NULL)
@@ -4962,6 +4965,7 @@
|| bfd_bread (buf, size, abfd) != size)
error (_("Dwarf Error: Can't read DWARF data from '%s'"),
bfd_get_filename (abfd));
+ }
return buf;
}
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH] Use mmap for symbol tables
2006-01-29 23:36 Eirik Fuller
@ 2006-01-30 5:04 ` Jim Blandy
2006-01-30 11:44 ` Eirik Fuller
2006-01-30 11:34 ` Andrew STUBBS
2006-01-31 2:23 ` Daniel Jacobowitz
2 siblings, 1 reply; 31+ messages in thread
From: Jim Blandy @ 2006-01-30 5:04 UTC (permalink / raw)
To: Eirik Fuller; +Cc: gdb-patches
What kind of effect does this have on performance? Is there a speed
benefit to it, or is it just that it allows multiple GDB's to share
memory?
I believe you might as well use MAP_PRIVATE, not MAP_SHARED. The
kernel will still share memory with the block cache, the pages will
just be copy-on-write. You don't want bugs in GDB to corrupt your
executables.
I understand that it would make your BFD code more complicated, but it
seems to me you want to map individual sections, not entire files.
Again, this will still share memory with the block cache, so aside
from the complexity I don't see the downside.
The last time this was brought up, there was concern about mmap's
reliability and portability, but if I remember right, people weren't
specific about exactly where the problems were to be expected. If
this is a decent performance win, I think we should consider it, and
sort out those portability issues as they arise.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-30 5:04 ` Jim Blandy
@ 2006-01-30 11:44 ` Eirik Fuller
2006-01-30 18:07 ` Jim Blandy
0 siblings, 1 reply; 31+ messages in thread
From: Eirik Fuller @ 2006-01-30 11:44 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
> What kind of effect does this have on performance? Is there a speed
> benefit to it, or is it just that it allows multiple GDB's to share
> memory?
I haven't done careful timings, but I suspect it speeds up gdb.
Without the patch there are two cases. (I work at Network Appliance, so
it's no surprise that I access all of the symbol tables through NFS :-).
On a fresh mount, there are two stages. The first stage is scattered
system CPU time and saturated network reads (that's the read syscall).
The second stage is 100% user time CPU on one processor.
On a mount that's been around long enough to have the entire symbol
table cached, the first stage is 100% CPU time, all system time, with no
extra network traffic (but for a shorter time than the first stage in a
fresh mount); that's the read syscall from cache. The second stage is
100% user time CPU, same as the fresh mount case.
With the patch, the first stage (the read syscall) goes away; access to
the symbol table is all page faults. With a fresh mount there's a
mixture of system time and user time, not quite 100% total because of
I/O delays; network traffic runs about half of the capacity of my
100BaseT interface (with suitable threading or readahead I could
probably peg the network interface, and have 100% user time CPU). With
the symbol table in cache, it's similar to the case without the patch,
without the brief syscall (100% system time) interval.
So for a fresh mount, the patch essentially interleaves the network
traffic and the 100% user space CPU. As I mentioned, I don't have any
specific numbers for the elapsed time, but I'm suddenly realizing that
having such numbers might be helpful. :-)
I suspect the biggest impact on performance isn't the startup time, but
rather the gdb memory footprint. With the patch, I never start pushing
stuff into swap on a 2GB system. Without the patch, it only takes a few
instances of gdb to fill up memory with what I think of as the green bar
in xosview (the xosview memory bar labels USED+SHAR/BUFF/CACHE/FREE as
green/orange/red/light blue). The BUFF part is always minimal; the mmap
patch reduces growth of the green bar so that only the red bar really
grows (and it grows without the patch too).
Actually, with that memory leak I mentioned, it only takes one instance
of gdb to fill the green bar, if I reload the symbol table a few times.
> You don't want bugs in GDB to corrupt your executables.
That's true, which is why my patch uses PROT_READ. In several years of
using the patch (sorry about that, keeping it to myself that long) that
has never caused a segfault, but if gdb ever decides to modify the mmap
region, that will crash gdb rather than corrupting the executable. In
my case I typically don't have write access to the symbol tables anyway,
but even for executables I own, PROT_READ won't let me change them.
> I understand that it would make your BFD code more complicated, but it
> seems to me you want to map individual sections, not entire files.
> Again, this will still share memory with the block cache, so aside
> from the complexity I don't see the downside.
I don't see the upside of making the code more complicated. The
downside of the extra complication is that it makes the patch less
likely to the point of never actually existing. :-)
Could you be more specific about why multiple mmap regions per file are
preferable? (It might help to keep in mind that I'm using PROT_READ and
MAP_SHARED). The only downside I can see is the (relatively small)
fraction of each symbol table which is not accessed via mmap, but that
doesn't use memory, just virtual address space (if it does use memory,
that contradicts the "not accessed" part).
> The last time this was brought up, there was concern about mmap's
> reliability and portability, but if I remember right, people weren't
> specific about exactly where the problems were to be expected.
I have nothing to offer in the way of speculation about what might be
wrong with using mmap, but I can offer years of experience which says it
works fine for me, on Linux systems using TCP NFS mounts over 2.4
kernels. I suspect 2.6 kernels work fine too, but that hasn't gotten
nearly as much testing as 2.4 kernels. It's possible other mmap
implementations aren't as good.
> If this is a decent performance win, I think we should consider it,
> and sort out those portability issues as they arise.
One very simple way to evaluate such a patch is to automatically add it
at configure time to any system which claims to provide mmap, and
disable it by default, with a variable which enables it on the fly.
That would make it easy to measure the effect on performance, because a
single gdb binary could be used either way. I could roll up a modified
patch to that effect, perhaps with the other things I mentioned (changes
to the configure script, a ChangeLog entry, documentation, test cases).
I would also be interested in hearing about the results if anyone else
tries the patch I already sent. I'd expect the improvement to be more
dramatic on large symbol tables than small ones. As an example, one of
the symbol tables I used for my recent testing is over 300MB, with over
20MB of just text segment.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-30 11:44 ` Eirik Fuller
@ 2006-01-30 18:07 ` Jim Blandy
2006-01-30 18:59 ` Eirik Fuller
2006-02-01 6:04 ` Michael Snyder
0 siblings, 2 replies; 31+ messages in thread
From: Jim Blandy @ 2006-01-30 18:07 UTC (permalink / raw)
To: Eirik Fuller; +Cc: gdb-patches
That's interesting. Since GDB does make a complete pass through the
symbol information to build its partial symbol tables, I would have
expected that doing network I/O each time the scan touched a new page
would be horrible, latency-wise. But from what you've said, it sounds
like the kernel recognizes there's a linear scan going on and starts
doing read-ahead, so you can do the network I/O in parallel with GDB's
processing. Do I have that right?
I hadn't noticed that you'd mapped the data read-only. That's an even
better way of dealing with GDB bugs. It's nice to know we don't have
any of that sort. :)
However, doesn't that mean that changes to the data by other processes
(say) would become visible to GDB? What happens when you recompile
the program while GDB's running?
On 1/30/06, Eirik Fuller <eirik@hackrat.com> wrote:
> > I understand that it would make your BFD code more complicated, but it
> > seems to me you want to map individual sections, not entire files.
> > Again, this will still share memory with the block cache, so aside
> > from the complexity I don't see the downside.
>
> I don't see the upside of making the code more complicated. The
> downside of the extra complication is that it makes the patch less
> likely to the point of never actually existing. :-)
I know how that goes. :)
> Could you be more specific about why multiple mmap regions per file are
> preferable? (It might help to keep in mind that I'm using PROT_READ and
> MAP_SHARED). The only downside I can see is the (relatively small)
> fraction of each symbol table which is not accessed via mmap, but that
> doesn't use memory, just virtual address space (if it does use memory,
> that contradicts the "not accessed" part).
I'm just concerned about wasting address space. People these days do
have awfully big programs. There are executables out there in the
gigabytes (cue lurkers to share their horror stories).
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-30 18:07 ` Jim Blandy
@ 2006-01-30 18:59 ` Eirik Fuller
2006-01-30 22:11 ` Jim Blandy
2006-02-01 6:04 ` Michael Snyder
1 sibling, 1 reply; 31+ messages in thread
From: Eirik Fuller @ 2006-01-30 18:59 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
> But from what you've said, it sounds like the kernel recognizes
> there's a linear scan going on and starts doing read-ahead, so you can
> do the network I/O in parallel with GDB's processing. Do I have that
> right?
The read-ahead effect is imperfect, at least on the system I'm using.
If it were better, I'd saturate the network interface, but it's running
at more like half speed.
With a fresh mount (no symbol table caching), the mmap patch provides
interleaving. Without the patch, first it takes a long time to read the
entire symbol table into memory (which saturates the network interface),
then a second pass saturates the CPU. I really should make some actual
measurements; at this point I'm not entirely sure that the elapsed time
is less for a fresh mount (but it's certainly less after the symbol
table is in the file system cache ... but I should measure that too).
> However, doesn't that mean that changes to the data by other processes
> (say) would become visible to GDB? What happens when you recompile
> the program while GDB's running?
In our environment that's very rare (once a release ships, we really
need the symbol table to match what shipped), enough that I hadn't even
given it much thought, but I have a couple of offhand reactions.
One, it's roughly the same problem as NFS server outages (yes, the
details will vary; in our environment NFS outages are far more common
than symbol table clobberage).
Two, if the build process unlinks the symbol table before commencing the
link, gdb won't see the changes (at least not in mmap'd data). Renaming
the symbol table is better than unlinking, all in all, but unlinking it
is sufficient to rely on the unlinked open files feature (which, with
NFS, isn't enough; the conventional .nfs turd file hack is useless when
a different client unlinks the file). I just double checked; our
Makefiles do remove the old symbol table first.
In an earlier message I commented about problems which might occur while
fleshing out partial symbols, if a symbol table becomes unavailable. In
that commentary I assumed that gdb reads from the symbol table when it
promotes partial symbols to symbols; a quick glance at the code suggests
I assumed correctly. Does gdb handle a symbol table which changes out
from under it when it fleshes out partial symbols? If not, then the
mmap patch doesn't make things fundamentally worse; it's just a matter
of degree. If gdb does handle changes to a symbol table gracefully,
then I wonder if the way it does that can somehow be extended to mmap.
> I'm just concerned about wasting address space. People these days do
> have awfully big programs. There are executables out there in the
> gigabytes (cue lurkers to share their horror stories).
I've already mentioned that the wasted address space isn't all that big,
at least not in the symbol tables I'm accustomed to. Anyone who is
crowding the limits of virtual address space will run out soon enough
whether they use malloc/seek/read or mmap; the best long term answer,
short of a completely different symbol table format (one which doesn't
require slurping the entire file to build an index that belongs in the
file format to begin with), is to buy amd64 processors. I've already
bought myself a dual Opteron system for similar reasons, but that has
more to do with multi-gigabyte core files than big symbol tables.
If I had symbol tables big enough to crowd the address space limits on
the processor gdb runs on, I would switch to a new symbol table format.
At the very least I'd break the existing file into two pieces, the piece
gdb needs and the piece it doesn't need (but really it would be better
in the long run, for a number of reasons, to completely overhaul the
symbol table format).
One concern I have about extra complication to mmap pieces of the file
is that it could conceivably use more address space rather than less
address space. If different parts of gdb use overlapping regions of the
symbol table, the extra complication has to be careful to share an
existing mmap (or pay the penalty of mmaping it twice). The whole-file
approach to mmap eats the address space cost up front, but it never gets
any worse than the worst case.
I should point out that I don't have any evidence to support a concern
about mmaping regions more than once. I have a vague recollection, from
years ago, of being surprised that there were redundant mmap regions in
a gdb process, but I'm not even positive that it was for a symbol table.
The way I remember it, it might have been related to the use of the same
file for executable and symbol table, but I just don't remember the details.
I really should gather some timing information and pass it along. I'll
try to do that today.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-30 18:59 ` Eirik Fuller
@ 2006-01-30 22:11 ` Jim Blandy
2006-01-31 0:38 ` Eirik Fuller
0 siblings, 1 reply; 31+ messages in thread
From: Jim Blandy @ 2006-01-30 22:11 UTC (permalink / raw)
To: Eirik Fuller; +Cc: gdb-patches
On 1/30/06, Eirik Fuller <eirik@hackrat.com> wrote:
> > However, doesn't that mean that changes to the data by other processes
> > (say) would become visible to GDB? What happens when you recompile
> > the program while GDB's running?
>
> In our environment that's very rare (once a release ships, we really
> need the symbol table to match what shipped), enough that I hadn't even
> given it much thought, but I have a couple of offhand reactions.
>
> One, it's roughly the same problem as NFS server outages (yes, the
> details will vary; in our environment NFS outages are far more common
> than symbol table clobberage).
>
> Two, if the build process unlinks the symbol table before commencing the
> link, gdb won't see the changes (at least not in mmap'd data). Renaming
> the symbol table is better than unlinking, all in all, but unlinking it
> is sufficient to rely on the unlinked open files feature (which, with
> NFS, isn't enough; the conventional .nfs turd file hack is useless when
> a different client unlinks the file). I just double checked; our
> Makefiles do remove the old symbol table first.
For inclusion in the public GDB sources, I'd want GDB's sensitivity to
the files being changed out from underneath it to be unaffected,
regardless of the details of peoples' build processes. Right now, GDB
effectively has its own copy of the symbol data it will use until it
notices that the file has changed and re-reads it. GDB shouldn't
crash just because someone does '> a.out' on it. It's better to get
an error from bfd_seek or bfd_bread than a segfault from trying to
access file blocks that aren't there.
Have you explained the disadvantages to simply using MAP_PRIVATE? If
you have, I missed it. Does MAP_PRIVATE require the whole file to be
read before the mmap system call can return, like 'read' does?
> In an earlier message I commented about problems which might occur while
> fleshing out partial symbols, if a symbol table becomes unavailable. In
> that commentary I assumed that gdb reads from the symbol table when it
> promotes partial symbols to symbols; a quick glance at the code suggests
> I assumed correctly. Does gdb handle a symbol table which changes out
> from under it when it fleshes out partial symbols? If not, then the
> mmap patch doesn't make things fundamentally worse; it's just a matter
> of degree. If gdb does handle changes to a symbol table gracefully,
> then I wonder if the way it does that can somehow be extended to mmap.
At least with Dwarf 2, which is the format used by default these days,
GDB doesn't re-read anything at psymtab-to-symtab conversion time. It
keeps the whole thing in memory.
> I've already mentioned that the wasted address space isn't all that big,
> at least not in the symbol tables I'm accustomed to. Anyone who is
> crowding the limits of virtual address space will run out soon enough
> whether they use malloc/seek/read or mmap; the best long term answer,
> short of a completely different symbol table format (one which doesn't
> require slurping the entire file to build an index that belongs in the
> file format to begin with), is to buy amd64 processors. I've already
> bought myself a dual Opteron system for similar reasons, but that has
> more to do with multi-gigabyte core files than big symbol tables.
I'm glad it's not a problem for you, but I'm not sure that's the best
answer for all of GDB's users.
> One concern I have about extra complication to mmap pieces of the file
> is that it could conceivably use more address space rather than less
> address space. If different parts of gdb use overlapping regions of the
> symbol table
They don't, I'm pretty sure.
> I really should gather some timing information and pass it along. I'll
> try to do that today.
Great --- I'd love to see some timings.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-30 22:11 ` Jim Blandy
@ 2006-01-31 0:38 ` Eirik Fuller
2006-01-31 1:49 ` Jim Blandy
2006-01-31 21:48 ` Mark Kettenis
0 siblings, 2 replies; 31+ messages in thread
From: Eirik Fuller @ 2006-01-31 0:38 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
> For inclusion in the public GDB sources, I'd want GDB's sensitivity to
> the files being changed out from underneath it to be unaffected,
> regardless of the details of peoples' build processes.
Fair enough. Making the mmap patch a configure time option (not just
detecting the presence of mmap, but requiring that use of mmap to be
explictly enabled) would accomplish that. Or always compile it in if
mmap is detected at configure time but leave it disabled by default.
If it's available, but is enabled only by request, and if the associated
risks are documented, I don't think GDB's ability to handle changed
files is diminished in any meaningful sense.
Of course, ignoring mmap altogether would just as easily accomplish the
same goal. :-)
> Have you explained the disadvantages to simply using MAP_PRIVATE?
No, not yet.
> Does MAP_PRIVATE require the whole file to be read before the mmap
> system call can return, like 'read' does?
I doubt it. I'm not sure MAP_PRIVATE is any different than MAP_SHARED
if PROT_READ is specified. It's possible that MAP_PRIVATE preserves the
original file contents (MAP_SHARED certainly doesn't), but my reading of
the mmap man page tells me it makes no such promise.
> I'm glad it's not a problem for you, but I'm not sure that's the best
> answer for all of GDB's users.
Fair enough. I still think that anyone for whom mmap burns too much
address space is a few months of bloat away from losing the rest even
with malloc. :-)
> I'd love to see some timings.
All these years I'd assumed the mmap patch reduced startup time, but my
recent observations got me wondering (the network monitor bar in xosview
is a recent addition to my configuration). Now that I've actually done
some simple timings, I realize that the faster network throughput of
read (compared to mmap) reduces the total startup time, even though the
network I/O is amortized in the mmap case (the other way to see it is
that the CPU isn't busy all the time with a fresh mount, with mmap).
With a slightly modified patch (to make mmap runtime optional) I always
get around 42 seconds of user time CPU on the symbol table file I used
for the tests (between 42.35 and 42.71 in a total of four samplings;
that variation looks like noise). The system time for read is 3.22
seconds with the symbol table in cache and 3.67 seconds with a fresh
mount. The same numbers for mmap are 0.62 (in cache) and 1.9 seconds
(fresh mount), so the syscall time is less with mmap (no big there).
The elapsed time with the file in cache is 43.3 seconds with mmap and
45.6 seconds with read.
With a fresh mount, read takes 1:14 and mmap takes 1:33; that's
consistent with the lower network throughput I see with mmap, in
my xosview window. It might be interesting to compare network
traces between read and mmap, but it looks like read just does
better readahead than mmap.
I can reduce the gdb startup time on a fresh mount if I start dd on the
same file before I start gdb (yes, that's cheating :-)
My tests are on a dual 700 MHz PIII (yeah, so I like dinosaurs :-) with
2GB of PC-100 SDRAM and a single e100 network interface, full duplex.
The symbol table is a 336620600 byte DWARF/ELF file with segment sizes
of 22135266/2578672/33359212 (text/data/bss).
So for gdb startup time (which, I think, is the only place mmap makes a
different in CPU performance), the best case for mmap is only slightly
better than the best case for read, and the worst case for mmap is
noticably worse than the worst case for read.
In view of all that, I think it's fair to say that the real benefit of
the mmap patch is the memory footprint. Perhaps I'll find time to run
some simple benchmarks on a system with considerably less memory (when I
used gdb without my mmap patch on a dual 550 MHz Xeon with 768MB, it
seemed painfully slow; perhaps I should try to quantify that).
About the other issue (reacting in a reasonable manner to a symbol table
which disappears or changes out from under gdb), I agree that enabling
mmap by default on systems which support it would be a mistake.
I think it's a performance tradeoff which needs to be consciously
chosen, not inflicted on GDB users without their consent.
Having said that, I believe that enabling mmap for symbol tables makes
more sense in my environment than not enabling it. Unless that's an
extreme minority opinion, it seems like a vote in favor of adding (a
suitable mutation of) the patch and disabling it by default (but either
way, I'm free to use my own privately maintained GDB :-).
Thanks for your feedback!
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 0:38 ` Eirik Fuller
@ 2006-01-31 1:49 ` Jim Blandy
2006-01-31 3:12 ` Eirik Fuller
2006-01-31 21:48 ` Mark Kettenis
1 sibling, 1 reply; 31+ messages in thread
From: Jim Blandy @ 2006-01-31 1:49 UTC (permalink / raw)
To: Eirik Fuller; +Cc: gdb-patches
On 1/30/06, Eirik Fuller <eirik@hackrat.com> wrote:
> Thanks for your feedback!
Thank *you*! This has been really interesting, and your explanations
have been very helpful in understanding what's going on. The mmap
idea has been around for a long time, and it's great to have some real
data.
By the way, do you have the option of timing things with an executable
on a local disk? I think that's a very commonly used configuration
these days. (I always avoid linking via NFS if I can, and I'm kind of
lazy about that sort of stuff.)
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 1:49 ` Jim Blandy
@ 2006-01-31 3:12 ` Eirik Fuller
0 siblings, 0 replies; 31+ messages in thread
From: Eirik Fuller @ 2006-01-31 3:12 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
> By the way, do you have the option of timing things with an executable
> on a local disk?
Yes, I can do that. I can even use fresh mounts, to compare a populated
cache against an unpoplated cache (I suppose I could also rebuild
binaries as necessary, but with big binaries umount is easier).
I'm traveling all day tomorrow, but I can work on this later this week.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 0:38 ` Eirik Fuller
2006-01-31 1:49 ` Jim Blandy
@ 2006-01-31 21:48 ` Mark Kettenis
2006-02-01 17:52 ` Eirik Fuller
1 sibling, 1 reply; 31+ messages in thread
From: Mark Kettenis @ 2006-01-31 21:48 UTC (permalink / raw)
To: eirik; +Cc: jimb, gdb-patches
> Date: Mon, 30 Jan 2006 16:38:26 -0800
> From: Eirik Fuller <eirik@hackrat.com>
>
> > For inclusion in the public GDB sources, I'd want GDB's sensitivity to
> > the files being changed out from underneath it to be unaffected,
> > regardless of the details of peoples' build processes.
>
> Fair enough. Making the mmap patch a configure time option (not just
> detecting the presence of mmap, but requiring that use of mmap to be
> explictly enabled) would accomplish that. Or always compile it in if
> mmap is detected at configure time but leave it disabled by default.
> If it's available, but is enabled only by request, and if the associated
> risks are documented, I don't think GDB's ability to handle changed
> files is diminished in any meaningful sense.
Please be aware that even if a particular OS supports mmap(2), it may
not be able to mmap files on all filesystems. So you'll have to check
at runtime whether mmap is possible and if it fails fall back on the
old code that simply reads the file.
Mark
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 21:48 ` Mark Kettenis
@ 2006-02-01 17:52 ` Eirik Fuller
0 siblings, 0 replies; 31+ messages in thread
From: Eirik Fuller @ 2006-02-01 17:52 UTC (permalink / raw)
To: Mark Kettenis; +Cc: Jim Blandy, gdb-patches
> So you'll have to check at runtime whether mmap is possible and if it
> fails fall back on the old code that simply reads the file.
My patch does that. The compile time conditionals are, um, still in the
future, but the runtime check is, if mmap fails, act as though the call
had never occurred. Disabling the mmap code through a runtime config
option is similar. The trick is to not get rid of the fallback (the
original malloc/seek/read code); each chunk of the patch which adds a
call to mmap test the return value and falls through to the original
code if mmap fails. The calling code doesn't care whether the mmap
syscall failed, or mmap wasn't even called because of a config option.
It wouldn't be all that hard to handle mmap failures by disabling mmap;
that would eliminate the overhead of repeated mmap failures (replace it
by the overhead of repeated checks of the runtime config option value; I
assume that overhead is negligible).
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-30 18:07 ` Jim Blandy
2006-01-30 18:59 ` Eirik Fuller
@ 2006-02-01 6:04 ` Michael Snyder
1 sibling, 0 replies; 31+ messages in thread
From: Michael Snyder @ 2006-02-01 6:04 UTC (permalink / raw)
To: Jim Blandy; +Cc: Eirik Fuller, gdb-patches
> I'm just concerned about wasting address space. People these days do
> have awfully big programs. There are executables out there in the
> gigabytes (cue lurkers to share their horror stories).
>
<snrk> Hmm? Oh! Um...
Yeah, you're right, Jim. I've got users who have symbol files
with over a gigabyte of debug info.
Eirik, how about making this a user-specified option,
from the command line? Seems like that would facilitate
performance testing anyways... besides helping on platforms
that don't have mmap.
I noticed a side thread about gdb "scanning the symbol info linearly"
on the first pass, and my thought on THAT was... what makes you think
it's linear? With stabs it sure as hell isn't...
And another aside -- when one of my users with the gigabyte symtabs
tries to debug on a machine without enough physical memory, gdb
thrashes (naturally) -- but it thrashes BAD. For all practical
purposes, the initial symbol scan never terminates. That also
makes me doubt that the scan is linear.
One final ps -- this has been done before! It was put in,
and it was taken out again. One wonders if there was a reason
for taking it out. A brief glance at Changelogs suggests that
it was put in in 1992, and removed again in 1996. Hmm, here's
one that's poignant...
Wed Jan 31 13:34:52 1996 Fred Fish <fnf@cygnus.com>
* config/i386/xm-linux.h (MMAP_BASE_ADDRESS, MMAP_INCREMENT):
Define to what should be reasonable values. However, apparently
a bug in linux mmap prevents mapped symbol tables from working.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-29 23:36 Eirik Fuller
2006-01-30 5:04 ` Jim Blandy
@ 2006-01-30 11:34 ` Andrew STUBBS
2006-01-30 11:42 ` Corinna Vinschen
2006-01-31 2:23 ` Daniel Jacobowitz
2 siblings, 1 reply; 31+ messages in thread
From: Andrew STUBBS @ 2006-01-30 11:34 UTC (permalink / raw)
To: Eirik Fuller; +Cc: gdb-patches
Eirik Fuller wrote:
> My immediate goal is to solicit opinions on whether the basic approach
> is sound. Comments in gdb/dwarf2read.c indicate the idea is not new.
> I first started using an approach similar to what's in the enclosed
> patch long before I noticed those comments; those comments finally
> motivated me to dust this off.
I don't know much about mmap, so I'm not going to comment on the
specific implementation, but I do know it isn't available on all systems
GDB supports. E.g. Windows.
You'll need to put in a configure test and/or use conditional
compilation for this stuff.
You probably knew this already, but I thought I would mention it anyway.
Andrew Stubbs
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-30 11:34 ` Andrew STUBBS
@ 2006-01-30 11:42 ` Corinna Vinschen
2006-01-30 11:48 ` Andrew STUBBS
0 siblings, 1 reply; 31+ messages in thread
From: Corinna Vinschen @ 2006-01-30 11:42 UTC (permalink / raw)
To: gdb-patches
On Jan 30 11:31, Andrew STUBBS wrote:
> Eirik Fuller wrote:
> >My immediate goal is to solicit opinions on whether the basic approach
> >is sound. Comments in gdb/dwarf2read.c indicate the idea is not new.
> >I first started using an approach similar to what's in the enclosed
> >patch long before I noticed those comments; those comments finally
> >motivated me to dust this off.
>
> I don't know much about mmap, so I'm not going to comment on the
> specific implementation, but I do know it isn't available on all systems
> GDB supports. E.g. Windows.
It's available on Cygwin, so no problem here. As long as the autoconf
test isn't the old one which makes non-standard assumptions.
Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-30 11:42 ` Corinna Vinschen
@ 2006-01-30 11:48 ` Andrew STUBBS
0 siblings, 0 replies; 31+ messages in thread
From: Andrew STUBBS @ 2006-01-30 11:48 UTC (permalink / raw)
To: gdb-patches
Corinna Vinschen wrote:
> On Jan 30 11:31, Andrew STUBBS wrote:
>> Eirik Fuller wrote:
>>> My immediate goal is to solicit opinions on whether the basic approach
>>> is sound. Comments in gdb/dwarf2read.c indicate the idea is not new.
>>> I first started using an approach similar to what's in the enclosed
>>> patch long before I noticed those comments; those comments finally
>>> motivated me to dust this off.
>> I don't know much about mmap, so I'm not going to comment on the
>> specific implementation, but I do know it isn't available on all systems
>> GDB supports. E.g. Windows.
>
> It's available on Cygwin, so no problem here. As long as the autoconf
> test isn't the old one which makes non-standard assumptions.
But not on MinGW, IFAIK. I'm sure there are other such systems.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-29 23:36 Eirik Fuller
2006-01-30 5:04 ` Jim Blandy
2006-01-30 11:34 ` Andrew STUBBS
@ 2006-01-31 2:23 ` Daniel Jacobowitz
2006-01-31 3:31 ` Eirik Fuller
2006-01-31 5:28 ` Jim Blandy
2 siblings, 2 replies; 31+ messages in thread
From: Daniel Jacobowitz @ 2006-01-31 2:23 UTC (permalink / raw)
To: Eirik Fuller; +Cc: gdb-patches
Not a whole lot to add in addition to what others have already said.
One important note: you bypassed symfile_relocate_debug_section.
Instead, this logic ought to live in there; if the debug section
has relocations, we can't mmap it, because we do need to modify
everything we read from disk.
There's some benefits other than the obvious to using read-only
mmap; you'll get better hot-cache performance because two consecutive
sessions can do DWARF processing on pages already read in, rather than
memcpy'ing them from the page cache.
I've got no qualms about mmapping the whole object. We already are
likely to run into address space issues if the file is large enough
for this to matter. I'm not real sympathetic to tools which edit
debugged binaries in place; and any standard build tools will unlink
the old file.
We can do the same thing on Windows and if there's a use for it on Unix
systems someone should investigate whether an equivalent hack helps on
native Windows.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 2:23 ` Daniel Jacobowitz
@ 2006-01-31 3:31 ` Eirik Fuller
2006-01-31 3:38 ` Daniel Jacobowitz
2006-02-07 22:05 ` Eirik Fuller
2006-01-31 5:28 ` Jim Blandy
1 sibling, 2 replies; 31+ messages in thread
From: Eirik Fuller @ 2006-01-31 3:31 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
> One important note: you bypassed symfile_relocate_debug_section.
I'll look at it. It hasn't yet been an issue in anything I've used my
gdb mmap patches with, but offhand I'd expect it should be easy to find
something that does trip over that. I can watch attempts to write back
to the readonly mmap region from gdb, and maybe cobble together some
malloc glue which provides the illusion of copy on write. Or maybe just
convince myself that MAP_PRIVATE is the right answer (but it might be
better to keep PROT_READ, just to really keep track of what gdb needs to
modify and what it doesn't need to modify).
> you'll get better hot-cache performance because two consecutive
> sessions can do DWARF processing on pages already read in
That sounds similar to my earlier observation about the memory footprint
of concurrent gdb sessions on the same symbol table, but if I understand
correctly you're saying that even consecutive (non-overlapping) gdb
sessions can benefit if pages stay in the page cache. I think that was
visible to some extent in the comparative timing between read and mmap
for the case where the symbol table was already in the page cache (mmap
was roughly two seconds faster, 43 versus 45).
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 3:31 ` Eirik Fuller
@ 2006-01-31 3:38 ` Daniel Jacobowitz
2006-02-07 22:05 ` Eirik Fuller
1 sibling, 0 replies; 31+ messages in thread
From: Daniel Jacobowitz @ 2006-01-31 3:38 UTC (permalink / raw)
To: Eirik Fuller; +Cc: gdb-patches
On Mon, Jan 30, 2006 at 07:31:06PM -0800, Eirik Fuller wrote:
> > One important note: you bypassed symfile_relocate_debug_section.
>
> I'll look at it. It hasn't yet been an issue in anything I've used my
> gdb mmap patches with, but offhand I'd expect it should be easy to find
> something that does trip over that. I can watch attempts to write back
> to the readonly mmap region from gdb, and maybe cobble together some
> malloc glue which provides the illusion of copy on write. Or maybe just
> convince myself that MAP_PRIVATE is the right answer (but it might be
> better to keep PROT_READ, just to really keep track of what gdb needs to
> modify and what it doesn't need to modify).
No, probably you should just bypass the mmap if the code in that
function triggers.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 3:31 ` Eirik Fuller
2006-01-31 3:38 ` Daniel Jacobowitz
@ 2006-02-07 22:05 ` Eirik Fuller
2006-02-20 15:52 ` Daniel Jacobowitz
1 sibling, 1 reply; 31+ messages in thread
From: Eirik Fuller @ 2006-02-07 22:05 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
> One important note: you bypassed symfile_relocate_debug_section.
The first time I read this I didn't fully understand it (I just hadn't
really read that code yet). I think I understand it now.
I also saw comments near symfile_relocate_debug_section which suggest
that it won't be trivial to find a test case, contrary to my earlier
response. UPS delivered my disk drive from NewEgg today, which means
I should have a PowerPC GNU/Linux system soon (the disk will soon be
the second disk in my G5). I might still need to pay attention to
linker issues to fully explore this; I guess I'll find out soon. :-)
Nonetheless I do have this revised patch. On symbol tables I use it
seems to be equivalent to the one I sent earlier. I'm not resending
the entire patch, just the part that affects gdb/dwarf2read.c
One assumption in this revised patch which I haven't fully validated
is that it makes sense to free the obstack_alloc'd buf if bfd_fetch
returns a non-NULL value. I figure if symfile_relocate_debug_section
returns NULL, either there were no subsequent calls to obstack_alloc,
or nothing allocated by obstack_alloc after buf matters any more. I'm
sure there's a cleaner way to approach this (which almost certainly
requires a bit more complication in the patch), but if the mmap calls
are eventually per-section in the BFD code (due to other complications
in the patch) instead of covering an entire file, this piece of the
patch will presumably look very different anyway.
> No, probably you should just bypass the mmap if the code in that
> function triggers.
I think this revised patch fits that description, by deferring the
call to bfd_fetch.
--- gdb/dwarf2read.c.orig 2006-01-17 14:30:29.000000000 -0800
+++ gdb/dwarf2read.c 2006-02-07 12:57:46.000000000 -0800
@@ -4958,6 +4958,13 @@
if (retbuf != NULL)
return retbuf;
+ retbuf = bfd_fetch(sectp->filepos, size, abfd);
+ if (retbuf != NULL)
+ {
+ obstack_free(&objfile->objfile_obstack, buf);
+ return retbuf;
+ }
+
if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0
|| bfd_bread (buf, size, abfd) != size)
error (_("Dwarf Error: Can't read DWARF data from '%s'"),
^ permalink raw reply [flat|nested] 31+ messages in thread* Re: [PATCH] Use mmap for symbol tables
2006-02-07 22:05 ` Eirik Fuller
@ 2006-02-20 15:52 ` Daniel Jacobowitz
0 siblings, 0 replies; 31+ messages in thread
From: Daniel Jacobowitz @ 2006-02-20 15:52 UTC (permalink / raw)
To: Eirik Fuller; +Cc: gdb-patches
Still catching up on mail, as usual... sorry about the delay.
On Tue, Feb 07, 2006 at 02:05:34PM -0800, Eirik Fuller wrote:
> One assumption in this revised patch which I haven't fully validated
> is that it makes sense to free the obstack_alloc'd buf if bfd_fetch
> returns a non-NULL value. I figure if symfile_relocate_debug_section
> returns NULL, either there were no subsequent calls to obstack_alloc,
> or nothing allocated by obstack_alloc after buf matters any more.
This is a bad, bad, bad assumption. Cases where it's proper to use
obstack_free are few and far between, and they often make me go "then
why did we bother to allocate it?". It would probably be better
to do this in symfile_relocate_debug_section, and let it allocate
the buffer. You can do this by passing an obstack (possibly NULL)
to symfile_relocate_debug_section, instead of a buffer (possibly NULL).
> I'm
> sure there's a cleaner way to approach this (which almost certainly
> requires a bit more complication in the patch), but if the mmap calls
> are eventually per-section in the BFD code (due to other complications
> in the patch) instead of covering an entire file, this piece of the
> patch will presumably look very different anyway.
Probably true.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 2:23 ` Daniel Jacobowitz
2006-01-31 3:31 ` Eirik Fuller
@ 2006-01-31 5:28 ` Jim Blandy
2006-01-31 13:59 ` Daniel Jacobowitz
1 sibling, 1 reply; 31+ messages in thread
From: Jim Blandy @ 2006-01-31 5:28 UTC (permalink / raw)
To: Eirik Fuller, gdb-patches
On 1/30/06, Daniel Jacobowitz <drow@false.org> wrote:
> One important note: you bypassed symfile_relocate_debug_section.
> Instead, this logic ought to live in there; if the debug section
> has relocations, we can't mmap it, because we do need to modify
> everything we read from disk.
>
> There's some benefits other than the obvious to using read-only
> mmap; you'll get better hot-cache performance because two consecutive
> sessions can do DWARF processing on pages already read in, rather than
> memcpy'ing them from the page cache.
When debug sections have relocations, are they really covered with
relocs, or are the relocs rare? I thought that MAP_PRIVATE was
implemented using copy-on-write pages, so if the relocations are rare,
then MAP_PRIVATE would give you a writeable image that still shared as
much as possible.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] Use mmap for symbol tables
2006-01-31 5:28 ` Jim Blandy
@ 2006-01-31 13:59 ` Daniel Jacobowitz
0 siblings, 0 replies; 31+ messages in thread
From: Daniel Jacobowitz @ 2006-01-31 13:59 UTC (permalink / raw)
To: Jim Blandy; +Cc: Eirik Fuller, gdb-patches
On Mon, Jan 30, 2006 at 09:28:06PM -0800, Jim Blandy wrote:
> When debug sections have relocations, are they really covered with
> relocs, or are the relocs rare? I thought that MAP_PRIVATE was
> implemented using copy-on-write pages, so if the relocations are rare,
> then MAP_PRIVATE would give you a writeable image that still shared as
> much as possible.
Covered. There will be one for every reference to .debug_str,
.debug_ranges, et cetera.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2006-02-20 15:52 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-31 4:53 [PATCH] Use mmap for symbol tables David Anderson
-- strict thread matches above, loose matches on Subject: below --
2006-01-31 4:40 David Anderson
2006-01-31 5:00 ` Eirik Fuller
2006-01-31 5:34 ` Jim Blandy
2006-01-31 14:00 ` Daniel Jacobowitz
2006-01-31 18:39 ` Jim Blandy
2006-02-01 18:11 ` Eirik Fuller
2006-01-31 17:45 ` David Anderson
2006-01-31 18:24 ` Jim Blandy
2006-01-29 23:36 Eirik Fuller
2006-01-30 5:04 ` Jim Blandy
2006-01-30 11:44 ` Eirik Fuller
2006-01-30 18:07 ` Jim Blandy
2006-01-30 18:59 ` Eirik Fuller
2006-01-30 22:11 ` Jim Blandy
2006-01-31 0:38 ` Eirik Fuller
2006-01-31 1:49 ` Jim Blandy
2006-01-31 3:12 ` Eirik Fuller
2006-01-31 21:48 ` Mark Kettenis
2006-02-01 17:52 ` Eirik Fuller
2006-02-01 6:04 ` Michael Snyder
2006-01-30 11:34 ` Andrew STUBBS
2006-01-30 11:42 ` Corinna Vinschen
2006-01-30 11:48 ` Andrew STUBBS
2006-01-31 2:23 ` Daniel Jacobowitz
2006-01-31 3:31 ` Eirik Fuller
2006-01-31 3:38 ` Daniel Jacobowitz
2006-02-07 22:05 ` Eirik Fuller
2006-02-20 15:52 ` Daniel Jacobowitz
2006-01-31 5:28 ` Jim Blandy
2006-01-31 13:59 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox