This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: struct gmon_cg_arc_record
- To: drepper at cygnus dot com (Ulrich Drepper)
- Subject: Re: struct gmon_cg_arc_record
- From: Jes Sorensen <jes at linuxcare dot com>
- Date: 14 Nov 2000 23:24:22 +0100
- Cc: libc-hacker at sourceware dot cygnus dot com, binutils at sourceware dot cygnus dot com
- References: <200011141926.UAA20529@lxplus015.cern.ch> <m3ofzis52d.fsf@otr.mynet.cygnus.com> <d3r94eux9b.fsf@lxplus015.cern.ch> <m3aeb2s33g.fsf@otr.mynet.cygnus.com> <d3n1f2uvxu.fsf@lxplus015.cern.ch> <m34s1as27q.fsf@otr.mynet.cygnus.com> <d3itpquuhv.fsf@lxplus015.cern.ch> <m3n1f2qm6p.fsf@otr.mynet.cygnus.com>
Hi
I am Cc'ing the binutils list on this. To those of you on this list
who do not read libc-hacker, let me just give a brief description of
the problem:
Basically it looks like gprof was written with 32 bit architectures in
mind and the on disk format of gmon.out quite shows this. When
generating this format in memory on a machine like the ia64 we get
misaligned stores so it seemed like a good idea to change the format
at least for Linux/ia64. However it is not quite obvious whether
profile support actually works under Linux/Alpha at the moment since
there seems to be some inconsistency in the defines of the structures
gmon_cg_arc_record vs and raw_arc. Thus I have attached a patch that
cleans up the special casing of the struct formats for 64 bit
architestures as well as declare 'count' as a long under Linux. I
didn't dare to change this for OSF/1 etc.
>>>>> "Ulrich" == Ulrich Drepper <drepper@redhat.com> writes:
Ulrich> Jes Sorensen <jes@linuxcare.com> writes:
>> struct raw_arc { /* FIXME: Checking a host compiler define means
>> that we can't use a cross gprof to the alpha. */ #ifdef __alpha__
>> char from_pc[8]; char self_pc[8]; char count[8]; #else char
>> from_pc[4]; char self_pc[4]; char count[4]; #endif };
Ulrich> Doesn't this mean profiling on Alpha doesn't work at all?
Ulrich> THen of course we should change it.
Hmmm that was the impression I got at first, however looking a bit
more at the gprof source I see that they operate on two formats, a
binary and a run time format. Ie. for the Alpha they expect a count of
4 on the disk but it is moved to a count of 8 internally. Grmbl grmbl
grmbl.
gprof clearly tries to work on OSF/1 as well, however I can't find a
definition of the structures on the OSF/1 box I searched on so I
cannot verify what it expects.
Ulrich> No, you misread the definition. The hist_size field
Ulrich> corresponds to ncnt. The prof_rate rate to version. The
Ulrich> dimen and dimen_abbrev field correspond to the profrate and
Ulrich> spare field.
Ulrich> So we cannot simply add a new field, we would have to reorder
Ulrich> them. The question is: was it always like this? Profiling
Ulrich> certainly worked for x86.
Whoops, need to go study this some more I guess.
Anyway my conclusion would be to recommend that we change the binary
format for 64 bit arcitectures under Linux as you also recommended. It
sounds like Jakub agrees as well.
I have attached a patch for gprof for those who wants to play with it
and a patch for glibc.
Jes
2000-11-14 Jes Sorensen <jes@linuxcare.com>
* gmon.h: Make definitions of low_pc, high_pc, from_pc, self_pc
sizeof(char *) to work on 64 bit architectures and not just the
Alpha which was special cased.
* gmon_out.h (struct gmon_cg_arc_record): count element should be
64 bit on 64 bit architectures under Linux to match glibc-2.2.
--- gprof/gmong.h-old Sun Apr 4 16:42:59 1999
+++ gprof/gmon.h Tue Nov 14 17:04:31 2000
@@ -37,15 +37,8 @@
struct raw_phdr
{
- /* FIXME: Checking a host compiler define means that we can't use
- a cross gprof to the alpha. */
-#ifdef __alpha__
- char low_pc[8]; /* base pc address of sample buffer */
- char high_pc[8]; /* max pc address of sampled buffer */
-#else
- char low_pc[4]; /* base pc address of sample buffer */
- char high_pc[4]; /* max pc address of sampled buffer */
-#endif
+ char low_pc[sizeof (char *)]; /* base pc address of sample buffer */
+ char high_pc[sizeof (char *)]; /* max pc address of sampled buffer */
char ncnt[4]; /* size of sample buffer (plus this header) */
char version[4]; /* version number */
@@ -57,15 +50,8 @@
struct old_raw_phdr
{
- /* FIXME: Checking a host compiler define means that we can't use
- a cross gprof to the alpha. */
-#ifdef __alpha__
- char low_pc[8]; /* base pc address of sample buffer */
- char high_pc[8]; /* max pc address of sampled buffer */
-#else
- char low_pc[4]; /* base pc address of sample buffer */
- char high_pc[4]; /* max pc address of sampled buffer */
-#endif
+ char low_pc[sizeof (char *)]; /* base pc address of sample buffer */
+ char high_pc[sizeof (char *)]; /* max pc address of sampled buffer */
char ncnt[4]; /* size of sample buffer (plus this header) */
/* FIXME: Checking host compiler defines here means that we can't
@@ -134,15 +120,11 @@
*/
struct raw_arc
{
- /* FIXME: Checking a host compiler define means that we can't use
- a cross gprof to the alpha. */
-#ifdef __alpha__
- char from_pc[8];
- char self_pc[8];
- char count[8];
+ char from_pc[sizeof (char *)];
+ char self_pc[sizeof (char *)];
+#ifdef linux
+ char count[sizeof (char *)];
#else
- char from_pc[4];
- char self_pc[4];
char count[4];
#endif
};
--- gprof/gmon_out.h-old Tue Nov 14 16:46:44 2000
+++ gprof/gmon_out.h Tue Nov 14 17:01:14 2000
@@ -45,7 +45,11 @@
{
char from_pc[sizeof (char*)]; /* address within caller's body */
char self_pc[sizeof (char*)]; /* address within callee's body */
+#ifdef linux
+ char count[sizeof (char*)]; /* number of arc traversals */
+#else
char count[4]; /* number of arc traversals */
+#endif
};
#endif /* gmon_out_h */
----------------
For glibc:
2000-11-14 Jes Sorensen <jes@linuxcare.com>
* gmon/sys/gmon_out.h (struct gmon_cg_arc_record): Change size of
count element to sizeof (char *).
* gmon/gmon.c (write_call_graph):
--- /home/jes/cygnus/libc-2.2/gmon/sys/gmon_out.h Sun Aug 10 13:02:27 1997
+++ libc-2.2/gmon/sys/gmon_out.h Tue Nov 14 17:06:10 2000
@@ -72,7 +72,7 @@
{
char from_pc[sizeof (char *)]; /* address within caller's body */
char self_pc[sizeof (char *)]; /* address within callee's body */
- char count[4]; /* number of arc traversals */
+ char count[sizeof (char *)]; /* number of arc traversals */
};
__END_DECLS
--- /home/jes/cygnus/libc-2.2/gmon/gmon.c Tue Apr 18 22:39:11 2000
+++ libc-2.2/gmon/gmon.c Tue Nov 14 17:23:55 2000
@@ -239,7 +239,7 @@
*(char **) raw_arc[nfilled].from_pc = (char *) frompc;
*(char **) raw_arc[nfilled].self_pc =
(char *)_gmonparam.tos[to_index].selfpc;
- *(int *) raw_arc[nfilled].count = _gmonparam.tos[to_index].count;
+ *(long *) raw_arc[nfilled].count = _gmonparam.tos[to_index].count;
if (++nfilled == NARCS_PER_WRITEV)
{