Index: vg_errcontext.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_errcontext.c,v retrieving revision 1.36 diff -r1.36 vg_errcontext.c 44a45,49 > /* The list of generated suppression directives, as created by this > execution */ > static Supp* vg_gen_suppressions_list = NULL; > UInt vg_gen_suppressions_count = 0; > 205,246d209 < void VG_(gen_suppression)(Error* err) < { < Int i; < UChar buf[M_VG_ERRTXT]; < ExeContext* ec = VG_(get_error_where)(err); < Int stop_at = VG_(clo_backtrace_size); < Char* name = SK_(get_error_name)(err); < < if (NULL == name) { < VG_(message)(Vg_UserMsg, "(skin does not allow error to be suppressed)"); < return; < } < < if (stop_at > 4) stop_at = 4; /* At most four names */ < vg_assert(stop_at > 0); < < VG_(printf)("{\n"); < VG_(printf)(" \n"); < VG_(printf)(" %s:%s\n", VG_(details).name, name); < SK_(print_extra_suppression_info)(err); < < /* This loop condensed from VG_(mini_stack_dump)() */ < i = 0; < do { < Addr eip = ec->eips[i]; < if (i > 0) < eip--; /* point to calling line */ < < if ( VG_(get_fnname_nodemangle) (eip, buf, M_VG_ERRTXT) ) { < VG_(printf)(" fun:%s\n", buf); < } else if ( VG_(get_objname)(eip, buf, M_VG_ERRTXT) ) { < VG_(printf)(" obj:%s\n", buf); < } else { < VG_(printf)(" ???:??? " < "# unknown, suppression will not work, sorry)\n"); < } < i++; < } while (i < stop_at && ec->eips[i] != 0); < < VG_(printf)("}\n"); < } < 258,259c221,222 < if (VG_(is_action_requested)( "Print suppression", < & VG_(clo_gen_suppressions) )) { --- > if ((VG_(clo_suppfile_fd) != -1) || > (VG_(is_action_requested)( "Print suppression", & VG_(clo_gen_suppressions) ))) { 871a835,1035 > } > > void VG_(gen_suppression)(Error* err) > { > Int i; > UChar buf[M_VG_ERRTXT]; > UChar effective_name[2*(M_VG_ERRTXT+1)]; > ExeContext* ec = VG_(get_error_where)(err); > Int stop_at = VG_(clo_backtrace_size); > Char* name = SK_(get_error_name)(err); > Supp * supp; > > if (NULL == name) { > VG_(message)(Vg_UserMsg, "(skin does not allow error to be suppressed)"); > return; > } > > if (stop_at > 4) stop_at = 4; /* At most four names */ > vg_assert(stop_at > 0); > > if(VG_(clo_suppfile_fd) != -1) { > Char caller_obj[VG_N_SUPP_CALLERS][M_VG_ERRTXT]; > Char caller_fun[VG_N_SUPP_CALLERS][M_VG_ERRTXT]; > > vg_gen_suppressions_count++; > for (i = 0; i < VG_N_SUPP_CALLERS; i++) > caller_obj[i][0] = caller_fun[i][0] = 0; > for (i = 0; i < VG_N_SUPP_CALLERS && i < VG_(clo_backtrace_size); i++) { > get_objname_fnname ( err->where->eips[i], caller_obj[i], M_VG_ERRTXT, > caller_fun[i], M_VG_ERRTXT ); > } > > /* We have to print to file, so store frequency counts */ > for(supp = vg_gen_suppressions_list;supp !=NULL; supp=supp->next) { > if(supp_matches_error(supp, err) && > supp_matches_callers(supp, caller_obj, caller_fun)) { > supp->count++; > return; > } > } > > /* If we reached here, implies this is a new supp never seen */ > supp = VG_(arena_malloc)(VG_AR_CORE, sizeof(Supp)); > for (i = 0; i < VG_N_SUPP_CALLERS; i++) supp->caller[i] = NULL; > supp->string = supp->extra = NULL; > > /* Setup Stuff inside supp for our uses */ > supp->count = 1; > VG_(sprintf)(effective_name,"%s:%s",VG_(details).name, name); > supp->sname = VG_(arena_strdup)(VG_AR_CORE, effective_name); > if (VG_STREQ(name, "PThread")) > supp->skind = PThreadSupp; > else > SK_(recognised_suppression)(name, supp); > > for (i = 0; i < stop_at; i++) { > Addr eip = ec->eips[i]; > if(i > 0) > eip--; /* point to calling line */ > if ( VG_(get_fnname_nodemangle) (eip, buf, M_VG_ERRTXT) ) { > supp->caller_ty[i] = FunName; > supp->caller[i] = VG_(arena_strdup(VG_AR_CORE, buf)); > } else if ( VG_(get_objname)(eip, buf, M_VG_ERRTXT) ) { > supp->caller_ty[i] = ObjName; > supp->caller[i] = VG_(arena_strdup(VG_AR_CORE, buf)); > } else { > VG_(printf)(" ???:??? " > "# unknown, suppression will not work, sorry)\n"); > return; > } > } > > /* Append at the end of existing list */ > supp->next = vg_gen_suppressions_list; > vg_gen_suppressions_list = supp; > return; > } > > /* Normal ; print to std and continue*/ > VG_(printf)("{\n"); > VG_(printf)(" \n"); > VG_(printf)(" %s:%s\n", VG_(details).name, name); > SK_(print_extra_suppression_info)(err); > > /* This loop condensed from VG_(mini_stack_dump)() */ > i = 0; > do { > Addr eip = ec->eips[i]; > if (i > 0) > eip--; /* point to calling line */ > > if ( VG_(get_fnname_nodemangle) (eip, buf, M_VG_ERRTXT) ) { > VG_(printf)(" fun:%s\n", buf); > } else if ( VG_(get_objname)(eip, buf, M_VG_ERRTXT) ) { > VG_(printf)(" obj:%s\n", buf); > } else { > VG_(printf)(" ???:??? " > "# unknown, suppression will not work, sorry)\n"); > } > i++; > } while (i < stop_at && ec->eips[i] != 0); > VG_(printf)("}\n"); > } > > void VG_(writeout_suppression)(void) > { > Int still_sorting = 1, nbytes = 0, i = 0; > Supp * prev, * curr; > UChar generated_suppression_name[4*(M_VG_ERRTXT+1)]; > UChar buf[6*(M_VG_ERRTXT+1)]; > UChar * current, * reset_library; > > /* Be paranoid */ > vg_assert(VG_(clo_suppfile_fd) > 0); > if(vg_gen_suppressions_list == NULL) { > VG_(close)(VG_(clo_suppfile_fd)); > return; > } > nbytes = VG_(sprintf)(buf, "###############################################\n" > "# Auto generated Suppressions for ==%d==\n" > "# Total suppressions seen: %d\n" > "###############################################\n\n", VG_(getpid)(), vg_gen_suppressions_count); > VG_(write) ( VG_(clo_suppfile_fd), buf, nbytes); > > /* Do you really need to sort ? */ > if(vg_gen_suppressions_list->next != NULL) { > > /* Sort based on Frequency, descending order*/ > while(still_sorting) { > still_sorting = 0; > > /* Adjust the head differently*/ > curr = vg_gen_suppressions_list; > if(curr->count < curr->next->count) { > vg_gen_suppressions_list = curr->next; > curr->next = vg_gen_suppressions_list->next; > vg_gen_suppressions_list->next = curr; > still_sorting = 1; > } > > prev = vg_gen_suppressions_list; > curr = vg_gen_suppressions_list->next; > for( ; curr->next != NULL ; prev = prev->next, curr = curr->next) { > if(curr->count < curr->next->count) { > prev->next = curr->next; > curr->next = prev->next->next; > prev->next->next = curr; > still_sorting = 1; curr = prev->next; > } > } > } > } > > /* Now that things are sorted, Dump contents to disk, generate name */ > for(curr = vg_gen_suppressions_list; curr != NULL; curr = curr->next) { > VG_(memset)(generated_suppression_name, 0, 4*(M_VG_ERRTXT+1)); > VG_(memset)(buf, 0, 6*(M_VG_ERRTXT+1)); > nbytes = 0; > > for(i=0;i<4;i++) { > if(curr->caller[i] != NULL) { > switch(curr->caller_ty[i]) { > case FunName: > VG_(strcat)(generated_suppression_name, curr->caller[i]); > break; > case ObjName: > for ( current = curr->caller[i], reset_library = current; > *current != 0; current++) { > if (*current == '/') > reset_library = current+1; > } > VG_(strcat)(generated_suppression_name, reset_library); > break; > } > VG_(strcat)(generated_suppression_name, "/"); > } > } > VG_(strcat)(generated_suppression_name,"auto-gen"); > > /* Use nbytes to get equiv of fprintf */ > nbytes += VG_(sprintf)(buf+nbytes, "# frequency: %u\n", curr->count); > nbytes += VG_(sprintf)(buf+nbytes, "{\n"); > nbytes += VG_(sprintf)(buf+nbytes, " %s\n", generated_suppression_name); > nbytes += VG_(sprintf)(buf+nbytes, " %s\n", curr->sname); > for(i=0;i<4;i++) { > if(curr->caller[i] != NULL) { > switch(curr->caller_ty[i]) { > case FunName: > nbytes += VG_(sprintf)(buf+nbytes, " fun:%s\n", curr->caller[i]); > break; > case ObjName: > nbytes += VG_(sprintf)(buf+nbytes, " obj:%s\n", curr->caller[i]); > break; > } > } > } > nbytes += VG_(sprintf)(buf+nbytes, "}\n\n"); > vg_assert(nbytes < 6*(M_VG_ERRTXT+1)); > VG_(write) ( VG_(clo_suppfile_fd), buf, nbytes); > } > VG_(close) ( VG_(clo_suppfile_fd)); Index: vg_include.h =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_include.h,v retrieving revision 1.132 diff -r1.132 vg_include.h 179a180,182 > /* Automatically log generated suppresions into a file? default: NO */ > extern Char* VG_(clo_suppfile_name); > extern Int VG_(clo_suppfile_fd); 1250a1254,1255 > > extern void VG_(writeout_suppression) ( void ); Index: vg_main.c =================================================================== RCS file: /cvsroot/valgrind/valgrind/coregrind/vg_main.c,v retrieving revision 1.99 diff -r1.99 vg_main.c 515a516,517 > Char* VG_(clo_suppfile_name) = NULL; > Int VG_(clo_suppfile_fd) = -1; 613c615,617 < " --gen-suppressions=no|yes print suppressions for errors detected [no]\n" --- > " --gen-suppressions=no| print suppressions for errors detected [no]\n" > " yes| print suppressions to stdout\n" > " print suppressions to file\n" 926a931,934 > else if (VG_CLO_STREQN(19, argv[i], "--gen-suppressions=")) { > VG_(clo_gen_suppressions) = True; > VG_(clo_suppfile_name) = &argv[i][19]; > } 1197a1206,1225 > /* If we are logging suppressions to a file, startup the file now */ > if ((VG_(clo_gen_suppressions) == True) && (VG_(clo_suppfile_name) != NULL)) { > Char suppfilename[1000]; > Int eventually_suppfile_fd; > vg_assert(VG_(strlen)(VG_(clo_suppfile_name)) <= 900); /* paranoia */ > VG_(sprintf)(suppfilename, "%s.pid%d", > VG_(clo_suppfile_name), VG_(getpid)() ); > eventually_suppfile_fd > = VG_(open)(suppfilename, VKI_O_CREAT|VKI_O_WRONLY, > VKI_S_IRUSR|VKI_S_IWUSR); > if (eventually_suppfile_fd != -1) { > VG_(clo_suppfile_fd) = eventually_suppfile_fd; > } else { > VG_(message)(Vg_UserMsg, > "Can't create/open suppressions file `%s.pid%d'; giving up!", > VG_(clo_suppfile_name), VG_(getpid)()); > VG_(bad_option)( > "--gen-suppressions= didn't work out for some reason."); > } > } 1555a1584,1586 > > if (VG_(clo_suppfile_fd) != -1) > VG_(writeout_suppression)();