lkml.org 
[lkml]   [2004]   [Aug]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [util-linux] readprofile ignores the last element in /proc/profile
    On Monday 30 August 2004 01:22, William Lee Irwin III wrote:
    >> Well, since I couldn't stop vomiting for hours after I looked at the
    >> code for readprofile(1), here's a reimplementation, with various
    >> misfeatures removed, included as a MIME attachment.

    On Wed, Sep 01, 2004 at 01:45:51AM +0900, mita akinobu wrote:
    > The rewritten readprofile still ignores the last element on my machine.
    > Boot option:
    > profile=2
    > System.map:
    > c0100264 t ignore_int
    > c0100298 T _stext
    > c0100298 T calibrate_delay
    > [...]
    > c03acbf1 T __spinlock_text_end
    > c03ae0af A _etext
    > c03ae0b0 A __start___ex_table

    It can't find anything outside a symbol in System.map, as it's
    iterating over symbols in System.map. Special treatment for the final
    profile buffer position is likely in order.


    On Wed, Sep 01, 2004 at 01:45:51AM +0900, mita akinobu wrote:
    > This is quick fix.
    > --- readprofile.c.orig 2004-08-31 23:01:23.000000000 +0900
    > +++ readprofile.c 2004-09-01 01:39:00.316750264 +0900
    > @@ -25,6 +25,7 @@ struct profile_state {
    > int fd, shift;
    > uint32_t *buf;
    > size_t bufsz;
    > + size_t bufcnt;
    > struct sym syms[2], *last, *this;
    > unsigned long long stext, vaddr;
    > unsigned long total;
    > @@ -101,8 +102,8 @@ 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;

    So the last read is always short, which is irritating; but bufcnt needs
    to be ssize_t or the nonnegativity condition can never fail. Otherwise
    it will report bogus results or terminate in a disorderly fashion if
    the read() fails outright, e.g. running out of memory or interruption
    by signals. So I propose the following alternative patch.


    -- wli


    --- readprofile.c.orig2 2004-08-31 12:11:54.000000000 -0700
    +++ readprofile.c 2004-08-31 12:13:44.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;
    -
    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.023 / U:29.684 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site