debuggers.hg

changeset 20969:b4ad00da6960

tools/xenbaked: fix bug of Segmentation fault

Run xenbaked will cause Segmentation fault, because
the method to get pointers of trace buffer metadata
is wrong. Fix this bug according to xentrace.

Signed-off-by: Yu Zhiguo <yuzg@cn.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Feb 10 13:30:57 2010 +0000 (2010-02-10)
parents 4b2aa9c350e6
children 8616a82df1c0
files tools/xenmon/xenbaked.c
line diff
     1.1 --- a/tools/xenmon/xenbaked.c	Wed Feb 10 13:30:16 2010 +0000
     1.2 +++ b/tools/xenmon/xenbaked.c	Wed Feb 10 13:30:57 2010 +0000
     1.3 @@ -83,6 +83,12 @@ typedef struct settings_st {
     1.4      double cpu_freq;
     1.5  } settings_t;
     1.6  
     1.7 +struct t_struct {
     1.8 +    struct t_info *t_info;  /* Structure with information about individual buffers */
     1.9 +    struct t_buf **meta;    /* Pointers to trace buffer metadata */
    1.10 +    unsigned char **data;   /* Pointers to trace buffer data areas */
    1.11 +};
    1.12 +
    1.13  settings_t opts;
    1.14  
    1.15  int interrupted = 0; /* gets set if we get a SIGHUP */
    1.16 @@ -356,96 +362,72 @@ static void disable_tracing(void)
    1.17   *
    1.18   * Maps the Xen trace buffers them into process address space.
    1.19   */
    1.20 -static struct t_buf *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
    1.21 -                        unsigned long size)
    1.22 +static struct t_struct *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
    1.23 +                                  unsigned long tinfo_size)
    1.24  {
    1.25      int xc_handle;
    1.26 -    struct t_buf *tbufs_mapped;
    1.27 +    static struct t_struct tbufs = { 0 };
    1.28 +    int i;
    1.29  
    1.30      xc_handle = xc_interface_open();
    1.31 -
    1.32      if ( xc_handle < 0 ) 
    1.33      {
    1.34          exit(EXIT_FAILURE);
    1.35      }
    1.36  
    1.37 -    tbufs_mapped = xc_map_foreign_range(xc_handle, DOMID_XEN,
    1.38 -                                        size * num, PROT_READ | PROT_WRITE,
    1.39 +    /* Map t_info metadata structure */
    1.40 +    tbufs.t_info = xc_map_foreign_range(xc_handle, DOMID_XEN,
    1.41 +                                        tinfo_size, PROT_READ | PROT_WRITE,
    1.42                                          tbufs_mfn);
    1.43  
    1.44 -    xc_interface_close(xc_handle);
    1.45 -
    1.46 -    if ( tbufs_mapped == 0 ) 
    1.47 +    if ( tbufs.t_info == 0 ) 
    1.48      {
    1.49          PERROR("Failed to mmap trace buffers");
    1.50          exit(EXIT_FAILURE);
    1.51      }
    1.52  
    1.53 -    return tbufs_mapped;
    1.54 -}
    1.55 +    if ( tbufs.t_info->tbuf_size == 0 )
    1.56 +    {
    1.57 +        fprintf(stderr, "%s: tbuf_size 0!\n", __func__);
    1.58 +        exit(EXIT_FAILURE);
    1.59 +    }
    1.60  
    1.61 -/**
    1.62 - * init_bufs_ptrs - initialises an array of pointers to the trace buffers
    1.63 - * @bufs_mapped:    the userspace address where the trace buffers are mapped
    1.64 - * @num:            number of trace buffers
    1.65 - * @size:           trace buffer size
    1.66 - *
    1.67 - * Initialises an array of pointers to individual trace buffers within the
    1.68 - * mapped region containing all trace buffers.
    1.69 - */
    1.70 -static struct t_buf **init_bufs_ptrs(void *bufs_mapped, unsigned int num,
    1.71 -                              unsigned long size)
    1.72 -{
    1.73 -    int i;
    1.74 -    struct t_buf **user_ptrs;
    1.75 -
    1.76 -    user_ptrs = (struct t_buf **)calloc(num, sizeof(struct t_buf *));
    1.77 -    if ( user_ptrs == NULL )
    1.78 +    /* Map per-cpu buffers */
    1.79 +    tbufs.meta = (struct t_buf **)calloc(num, sizeof(struct t_buf *));
    1.80 +    tbufs.data = (unsigned char **)calloc(num, sizeof(unsigned char *));
    1.81 +    if ( tbufs.meta == NULL || tbufs.data == NULL )
    1.82      {
    1.83          PERROR( "Failed to allocate memory for buffer pointers\n");
    1.84          exit(EXIT_FAILURE);
    1.85      }
    1.86  
    1.87 -    /* initialise pointers to the trace buffers - given the size of a trace
    1.88 -     * buffer and the value of bufs_maped, we can easily calculate these */
    1.89 -    for ( i = 0; i<num; i++ )
    1.90 -        user_ptrs[i] = (struct t_buf *)((unsigned long)bufs_mapped + size * i);
    1.91 +    for(i=0; i<num; i++)
    1.92 +    {
    1.93 +        
    1.94 +        uint32_t *mfn_list = ((uint32_t *)tbufs.t_info) + tbufs.t_info->mfn_offset[i];
    1.95 +        int j;
    1.96 +        xen_pfn_t pfn_list[tbufs.t_info->tbuf_size];
    1.97  
    1.98 -    return user_ptrs;
    1.99 -}
   1.100 -
   1.101 +        for ( j=0; j<tbufs.t_info->tbuf_size; j++)
   1.102 +            pfn_list[j] = (xen_pfn_t)mfn_list[j];
   1.103  
   1.104 -/**
   1.105 - * init_rec_ptrs - initialises data area pointers to locations in user space
   1.106 - * @tbufs_mfn:     base mfn of the trace buffer area
   1.107 - * @tbufs_mapped:  user virtual address of base of trace buffer area
   1.108 - * @meta:          array of user-space pointers to struct t_buf's of metadata
   1.109 - * @num:           number of trace buffers
   1.110 - *
   1.111 - * Initialises data area pointers to the locations that data areas have been
   1.112 - * mapped in user space.  Note that the trace buffer metadata contains machine
   1.113 - * pointers - the array returned allows more convenient access to them.
   1.114 - */
   1.115 -static struct t_rec **init_rec_ptrs(struct t_buf **meta, unsigned int num)
   1.116 -{
   1.117 -    int i;
   1.118 -    struct t_rec **data;
   1.119 -    
   1.120 -    data = calloc(num, sizeof(struct t_rec *));
   1.121 -    if ( data == NULL )
   1.122 -    {
   1.123 -        PERROR("Failed to allocate memory for data pointers\n");
   1.124 -        exit(EXIT_FAILURE);
   1.125 +        tbufs.meta[i] = xc_map_foreign_batch(xc_handle, DOMID_XEN,
   1.126 +                                             PROT_READ | PROT_WRITE,
   1.127 +                                             pfn_list,
   1.128 +                                             tbufs.t_info->tbuf_size);
   1.129 +        if ( tbufs.meta[i] == NULL )
   1.130 +        {
   1.131 +            PERROR("Failed to map cpu buffer!");
   1.132 +            exit(EXIT_FAILURE);
   1.133 +        }
   1.134 +        tbufs.data[i] = (unsigned char *)(tbufs.meta[i]+1);
   1.135      }
   1.136  
   1.137 -    for ( i = 0; i < num; i++ )
   1.138 -        data[i] = (struct t_rec *)(meta[i] + 1);
   1.139 +    xc_interface_close(xc_handle);
   1.140  
   1.141 -    return data;
   1.142 +    return &tbufs;
   1.143  }
   1.144  
   1.145 -
   1.146 -
   1.147  /**
   1.148   * get_num_cpus - get the number of logical CPUs
   1.149   */
   1.150 @@ -469,7 +451,6 @@ static unsigned int get_num_cpus(void)
   1.151      return physinfo.nr_cpus;
   1.152  }
   1.153  
   1.154 -
   1.155  /**
   1.156   * monitor_tbufs - monitor the contents of tbufs
   1.157   */
   1.158 @@ -477,12 +458,13 @@ static int monitor_tbufs(void)
   1.159  {
   1.160      int i;
   1.161  
   1.162 -    void *tbufs_mapped;          /* pointer to where the tbufs are mapped    */
   1.163 +    struct t_struct *tbufs;      /* Pointer to hypervisor maps */
   1.164      struct t_buf **meta;         /* pointers to the trace buffer metadata    */
   1.165 -    char         **data;         /* pointers to the trace buffer data areas
   1.166 +    unsigned char **data;        /* pointers to the trace buffer data areas
   1.167                                    * where they are mapped into user space.   */
   1.168      unsigned long tbufs_mfn;     /* mfn of the tbufs                         */
   1.169      unsigned int  num;           /* number of trace buffers / logical CPUS   */
   1.170 +    unsigned long tinfo_size;    /* size of t_info metadata map              */
   1.171      unsigned long size;          /* size of a single trace buffer            */
   1.172  
   1.173      unsigned long data_size, rec_size;
   1.174 @@ -496,15 +478,15 @@ static int monitor_tbufs(void)
   1.175      printf("CPU Frequency = %7.2f\n", opts.cpu_freq);
   1.176      
   1.177      /* setup access to trace buffers */
   1.178 -    get_tbufs(&tbufs_mfn, &size);
   1.179 +    get_tbufs(&tbufs_mfn, &tinfo_size);
   1.180 +    tbufs = map_tbufs(tbufs_mfn, num, tinfo_size);
   1.181  
   1.182 -    tbufs_mapped = map_tbufs(tbufs_mfn, num, size);
   1.183 +    size = tbufs->t_info->tbuf_size * XC_PAGE_SIZE;
   1.184  
   1.185      data_size = size - sizeof(struct t_buf);
   1.186  
   1.187 -    /* build arrays of convenience ptrs */
   1.188 -    meta  = init_bufs_ptrs (tbufs_mapped, num, size);
   1.189 -    data  = (char **)init_rec_ptrs(meta, num);
   1.190 +    meta = tbufs->meta;
   1.191 +    data = tbufs->data;
   1.192  
   1.193      if ( eventchn_init() < 0 )
   1.194          fprintf(stderr, "Failed to initialize event channel; "