lkml.org 
[lkml]   [2004]   [Sep]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    SubjectRe: [util-linux] readprofile ignores the last element in /proc/profile
    Date
    On Wednesday 01 September 2004 04:45, William Lee Irwin III wrote:
    > Still wrong =( That needs to be strict inequality.
    >
    >
    > --- readprofile.c.orig2 2004-08-31 12:11:54.000000000 -0700
    > +++ readprofile.c 2004-08-31 12:44:25.000000000 -0700
    > @@ -65,6 +65,7 @@
    > int ret = 0;
    > long page_mask, start, end;
    > unsigned off;
    > + ssize_t bufcnt;
    >
    > if (!state->stext) {
    > if (!strcmp(state->sym, "_stext"))
    > @@ -101,8 +102,8 @@
    > exit(EXIT_FAILURE);
    > }
    > }
    > - if (read(state->fd, state->buf, end - start) == end - start) {
    > - for (off = 0; off < (end - start)/sizeof(uint32_t); ++off)
    > + if ((bufcnt = read(state->fd, state->buf, end - start)) > 0) {
    > + for (off = 0; off < bufcnt/sizeof(uint32_t); ++off)
    > state->last->hits += state->buf[off];
    > } else {
    > ret = 1;

    If you're passing profile=0 on boot, it exits very early.
    (when readprofile saw the symbol whose address is same with next line's
    symbol address)

    and,
    On ia64, the following System.map was generated:

    [...]
    a000000100000000 A _stext
    a000000100000000 A _text (*)
    a000000100000000 T ia64_ivt
    a000000100000000 t vhpt_miss

    Since the symbol "_text" (*) has absolute symbol type, it could not pass the
    is_text() check, and readprofile exits immediately.

    BTW, if profile=>1 is passed, The range between start and end in
    state_transition() is overlapped every call. Is it intentional?

    # readprofile -b (after applied below patch)

    [...]
    __wake_up_common:
    c011f1d8 47 (*)
    __wake_up:
    c011f1d8 47 (*)
    c011f1dc 2



    --- readprofile.c.orig 2004-09-02 00:04:55.904405440 +0900
    +++ readprofile.c 2004-09-02 00:37:37.277231448 +0900
    @@ -25,6 +25,7 @@ struct profile_state {
    int fd, shift;
    uint32_t *buf;
    size_t bufsz;
    + ssize_t bufcnt;
    struct sym syms[2], *last, *this;
    unsigned long long stext, vaddr;
    unsigned long total;
    @@ -60,6 +61,32 @@ static long profile_off(unsigned long lo
    return (((vaddr - state->stext) >> state->shift) + 1)*sizeof(uint32_t);
    }

    +int optBin;
    +
    +static void display_hits(struct profile_state *state)
    +{
    + char *name = state->last->name;
    + unsigned long hits = state->last->hits;
    +
    + if (!hits)
    + return;
    + if (!optBin)
    + printf("%*lu %s\n", digits(), hits, name);
    + else {
    + unsigned long long vaddr = state->last->vaddr;
    + int shift = state->shift;
    + unsigned int off;
    +
    + printf("%s:\n", name);
    + for (off = 0; off < state->bufcnt/sizeof(uint32_t); ++off)
    + if (state->buf[off]) {
    + printf("\t%*llx", digits(),
    + ((vaddr >> shift) + off) << shift);
    + printf("\t%*lu\n", digits(), state->buf[off]);
    + }
    + }
    +}
    +
    static int state_transition(struct profile_state *state)
    {
    int ret = 0;
    @@ -101,16 +128,14 @@ static int state_transition(struct profi
    exit(EXIT_FAILURE);
    }
    }
    - if (read(state->fd, state->buf, end - start) == end - start) {
    - for (off = 0; off < (end - start)/sizeof(uint32_t); ++off)
    + if ((state->bufcnt = read(state->fd, state->buf, end - start)) > 0) {
    + for (off = 0; off < state->bufcnt/sizeof(uint32_t); ++off)
    state->last->hits += state->buf[off];
    } else {
    ret = 1;
    strcpy(state->last->name, "*unknown*");
    }
    - if (state->last->hits)
    - printf("%*lu %s\n", digits(), state->last->hits,
    - state->last->name);
    + display_hits(state);
    state->total += state->last->hits;
    out:
    return ret;
    @@ -169,7 +194,7 @@ int main(int argc, char * const argv[])
    {
    FILE *system_map = NULL;
    int c, ret, profile_buffer = -1;
    - static const char optstr[] = "m:p:";
    + static const char optstr[] = "m:p:b";

    while ((c = getopt(argc, argv, optstr)) != EOF) {
    switch (c) {
    @@ -195,6 +220,9 @@ int main(int argc, char * const argv[])
    exit(EXIT_FAILURE);
    }
    break;
    + case 'b':
    + optBin = 1;
    + break;
    case '?':
    default:
    fprintf(stderr, "usage: %s [ -m mapfile ] "
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 14:05    [W:0.030 / U:62.532 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site