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>
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; "