18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file profile_spec.cpp 38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Contains a PP profile specification 48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2003 OProfile authors 68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Read the file COPYING 78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Philippe Elie 98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <algorithm> 128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <set> 138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <sstream> 148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iterator> 158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iostream> 168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <dirent.h> 178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "file_manip.h" 198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_config.h" 208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "profile_spec.h" 218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "string_manip.h" 228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "glob_filter.h" 238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "locate_images.h" 248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_exception.h" 258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_header.h" 268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "op_fileio.h" 278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std; 298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace { 318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// PP:3.7, full path, or relative path. If we can't find it, 338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// we should maintain the original to maintain the wordexp etc. 348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring const fixup_image_spec(string const & str, extra_images const & extra) 358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // On error find_image_path() return str, so if an occur we will 378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // use the provided image_name not the fixed one. 388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd image_error error; 398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return extra.find_image_path(str, error, true); 408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid fixup_image_spec(vector<string> & images, extra_images const & extra) 438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string>::iterator it = images.begin(); 458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string>::iterator const end = images.end(); 468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (; it != end; ++it) 488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *it = fixup_image_spec(*it, extra); 498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} // anon namespace 528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprofile_spec::profile_spec() 558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd : 568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd extra_found_images() 578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["archive"] = &profile_spec::parse_archive_path; 598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["session"] = &profile_spec::parse_session; 608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["session-exclude"] = 618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd &profile_spec::parse_session_exclude; 628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["image"] = &profile_spec::parse_image; 638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["image-exclude"] = &profile_spec::parse_image_exclude; 648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["lib-image"] = &profile_spec::parse_lib_image; 658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["event"] = &profile_spec::parse_event; 668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["count"] = &profile_spec::parse_count; 678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["unit-mask"] = &profile_spec::parse_unitmask; 688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["tid"] = &profile_spec::parse_tid; 698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["tgid"] = &profile_spec::parse_tgid; 708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table["cpu"] = &profile_spec::parse_cpu; 718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse(string const & tag_value) 758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string value; 778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd action_t action = get_handler(tag_value, value); 788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!action) { 798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd throw invalid_argument("profile_spec::parse(): not " 808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "a valid tag \"" + tag_value + "\""); 818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd (this->*action)(value); 848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool profile_spec::is_valid_tag(string const & tag_value) 888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string value; 908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return get_handler(tag_value, value); 918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::set_image_or_lib_name(string const & str) 958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* FIXME: what does spec say about this being allowed to be 978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * a comma list or not ? */ 988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd image_or_lib_image.push_back(fixup_image_spec(str, extra_found_images)); 998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_archive_path(string const & str) 1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd archive_path = op_realpath(str); 1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstring profile_spec::get_archive_path() const 1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return archive_path; 1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_session(string const & str) 1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd session = separate_token(str, ','); 1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_session_exclude(string const & str) 1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd session_exclude = separate_token(str, ','); 1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_image(string const & str) 1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd image = separate_token(str, ','); 1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd fixup_image_spec(image, extra_found_images); 1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_image_exclude(string const & str) 1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd image_exclude = separate_token(str, ','); 1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd fixup_image_spec(image_exclude, extra_found_images); 1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_lib_image(string const & str) 1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd lib_image = separate_token(str, ','); 1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd fixup_image_spec(lib_image, extra_found_images); 1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_event(string const & str) 1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd event.set(str); 1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_count(string const & str) 1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd count.set(str); 1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_unitmask(string const & str) 1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd unitmask.set(str); 1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_tid(string const & str) 1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tid.set(str); 1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_tgid(string const & str) 1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tgid.set(str); 1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid profile_spec::parse_cpu(string const & str) 1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cpu.set(str); 1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprofile_spec::action_t 1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprofile_spec::get_handler(string const & tag_value, string & value) 1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string::size_type pos = tag_value.find_first_of(':'); 1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (pos == string::npos) 1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string tag(tag_value.substr(0, pos)); 1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd value = tag_value.substr(pos + 1); 1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd parse_table_t::const_iterator it = parse_table.find(tag); 1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (it == parse_table.end()) 1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return 0; 1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return it->second; 1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace { 2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// return true if the value from the profile spec may match the comma 2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/// list 2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddtemplate<typename T> 2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool comma_match(comma_list<T> const & cl, generic_spec<T> const & value) 2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // if the profile spec is "all" we match the sample file 2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!cl.is_set()) 2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return true; 2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // an "all" sample file should never match specified profile 2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // spec values 2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!value.is_set()) 2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // now match each profile spec value against the sample file 2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return cl.match(value.value()); 2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool profile_spec::match(filename_spec const & spec) const 2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool matched_by_image_or_lib_image = false; 2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // We need the true image name not the one based on the sample 2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // filename for the benefit of module which have /oprofile in their 2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // sample filename. This allow to specify profile spec based on the 2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // real name of the image, e.g. 'binary:*oprofile.ko' 2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string simage = fixup_image_spec(spec.image, extra_found_images); 2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string slib_image = fixup_image_spec(spec.lib_image, 2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd extra_found_images); 2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // PP:3.19 2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!image_or_lib_image.empty()) { 2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd glob_filter filter(image_or_lib_image, image_exclude); 2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (filter.match(simage) || filter.match(slib_image)) 2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd matched_by_image_or_lib_image = true; 2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!matched_by_image_or_lib_image) { 2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // PP:3.7 3.8 2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!image.empty()) { 2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd glob_filter filter(image, image_exclude); 2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!filter.match(simage)) 2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else if (!image_or_lib_image.empty()) { 2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // image.empty() means match all except if user 2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // specified image_or_lib_image 2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // PP:3.9 3.10 2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!lib_image.empty()) { 2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd glob_filter filter(lib_image, image_exclude); 2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!filter.match(slib_image)) 2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else if (image.empty() && !image_or_lib_image.empty()) { 2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // lib_image empty means match all except if user 2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // specified image_or_lib_image *or* we already 2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // matched this spec through image 2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!matched_by_image_or_lib_image) { 2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // if we don't match by image_or_lib_image we must try to 2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // exclude from spec, exclusion from image_or_lib_image has 2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // been handled above 2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string> empty; 2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd glob_filter filter(empty, image_exclude); 2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!filter.match(simage)) 2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!spec.lib_image.empty() && !filter.match(slib_image)) 2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!event.match(spec.event)) 2818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!count.match(spec.count)) 2848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!unitmask.match(spec.unitmask)) 2878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!comma_match(cpu, spec.cpu)) 2908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!comma_match(tid, spec.tid)) 2938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!comma_match(tgid, spec.tgid)) 2968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 2978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 2988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return true; 2998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddprofile_spec profile_spec::create(list<string> const & args, 3038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string> const & image_path, 3048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string const & root_path) 3058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd profile_spec spec; 3078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd set<string> tag_seen; 3088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string> temp_image_or_lib; 3098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list<string>::const_iterator it = args.begin(); 3118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list<string>::const_iterator end = args.end(); 3128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (; it != end; ++it) { 3148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (spec.is_valid_tag(*it)) { 3158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (tag_seen.find(*it) != tag_seen.end()) { 3168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd throw op_runtime_error("tag specified " 3178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd "more than once: " + *it); 3188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd tag_seen.insert(*it); 3208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd spec.parse(*it); 3218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } else { 3228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string const file = op_realpath(*it); 3238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd temp_image_or_lib.push_back(file); 3248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // PP:3.5 no session given means use the current session. 3288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (spec.session.empty()) 3298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd spec.session.push_back("current"); 3308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool ok = true; 3328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string>::const_iterator ip_it = image_path.begin(); 3338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for ( ; ip_it != image_path.end(); ++ip_it) { 3348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!is_directory(spec.get_archive_path() + "/" + *ip_it)) { 3358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cerr << spec.get_archive_path() + "/" + *ip_it << " isn't a valid directory\n"; 3368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ok = false; 3378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!ok) 3408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd throw op_runtime_error("invalid --image-path= options"); 3418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd spec.extra_found_images.populate(image_path, spec.get_archive_path(), 3438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd root_path); 3448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string>::const_iterator im = temp_image_or_lib.begin(); 3458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string>::const_iterator last = temp_image_or_lib.end(); 3468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (; im != last; ++im) 3478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd spec.set_image_or_lib_name(*im); 3488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return spec; 3508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace { 3538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvector<string> filter_session(vector<string> const & session, 3558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string> const & session_exclude) 3568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string> result(session); 3588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (result.empty()) 3608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd result.push_back("current"); 3618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (size_t i = 0 ; i < session_exclude.size() ; ++i) { 3638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // FIXME: would we use fnmatch on each item, are we allowed 3648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // to --session=current* ? 3658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string>::iterator it = 3668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd find(result.begin(), result.end(), session_exclude[i]); 3678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (it != result.end()) 3698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd result.erase(it); 3708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 3718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return result; 3738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 3748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic bool invalid_sample_file; 3768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddbool valid_candidate(string const & base_dir, string const & filename, 3778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd profile_spec const & spec, bool exclude_dependent, 3788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool exclude_cg) 3798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 3808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (exclude_cg && filename.find("{cg}") != string::npos) 3818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 3828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // strip out non sample files 3848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string const & sub = filename.substr(base_dir.size(), string::npos); 3858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!is_prefix(sub, "/{root}/") && !is_prefix(sub, "/{kern}/")) 3868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 3878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 3888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd /* When overflows occur in the oprofile kernel driver's sample 3898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * buffers (caused by too high of a sampling rate), it's possible 3908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * for samples to be mis-attributed. A common scenario is that, 3918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * while profiling process 'abc' running binary 'xzy', the task 3928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * switch for 'abc' gets dropped somehow. Then, samples are taken 3938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * for the 'xyz' binary. In the attempt to attribute the samples to 3948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the associated binary, the oprofile kernel code examines the 3958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the memory mappings for the last process for which it recorded 3968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * a task switch. When profiling at a very high rate, the oprofile 3978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * daemon is often the process that is mistakenly examined. Then the 3988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * sample from binary 'xyz' is matched to some file that's open in 3998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * oprofiled's memory space. Because oprofiled has many sample files 4008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * open at any given time, there's a good chance the sample's VMA is 4018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * contained within one of those sample files. So, once finding this 4028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * bogus match, the oprofile kernel records a cookie switch for the 4038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * sample file. This scenario is made even more likely if a high 4048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * sampling rate (e.g., profiling on several events) is paired with 4058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * callgraph data collection. 4068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 4078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * When the daemon processes this sample data from the kernel, it 4088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * creates a sample file for the sample file, resulting in something 4098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * of the form: 4108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * <session-dir>/[blah]<session-dir>/[blah] 4118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 4128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * When the sample data is post-processed, the sample file is parsed to 4138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * try to determine the name of the binary, but it gets horribly confused. 4148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * At best, the post-processing tool will spit out some warning messages, 4158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * such as: 4168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * warning: 4178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * /lib64/libdl-2.9.so/CYCLES.10000.0.all.all.all/{dep}/{root}/var/lib/oprofile/samples/current/{root}/lib64/libdl-2.9.so/{dep}/{root}/lib64/libdl-2.9.so/PM_RUN_CYC_GRP12.10000.0.all.all.all 4188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * could not be found. 4198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 4208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * At worst, the parsing may result in an "invalid argument" runtime error 4218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * because of the inability to parse a sample file whose name contains that 4228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * of another sample file. This typically seems to happen when callgraph 4238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * data is being collected. 4248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * 4258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * The next several lines of code checks if the passed filename 4268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * contains <session-dir>/samples; if so, we discard it as an 4278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * invalid sample file. 4288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 4298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd unsigned int j = base_dir.rfind('/'); 4318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string session_samples_dir = base_dir.substr(0, j); 4328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (sub.find(session_samples_dir) != string::npos) { 4338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd invalid_sample_file = true; 4348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 4358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // strip out generated JIT object files for samples of anonymous regions 4388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (is_jit_sample(sub)) 4398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 4408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd filename_spec file_spec(filename, spec.extra_found_images); 4428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (spec.match(file_spec)) { 4438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (exclude_dependent && file_spec.is_dependent()) 4448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 4458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return true; 4468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return false; 4498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/** 4538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Print a warning message if we detect any sample buffer overflows 4548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * occurred in the kernel driver. 4558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */ 4568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid warn_if_kern_buffs_overflow(string const & session_samples_dir) 4578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 4588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd DIR * dir; 4598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd struct dirent * dirent; 4608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string stats_path; 4618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int ret = 0; 4628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd stats_path = session_samples_dir + "stats/"; 4648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ret = op_read_int_from_file((stats_path + "event_lost_overflow"). 4658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd c_str(), 0); 4668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!(dir = opendir(stats_path.c_str()))) { 4688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ret = -1; 4698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd goto done; 4708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd while ((dirent = readdir(dir)) && !ret) { 4738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd int cpu_nr; 4748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string path; 4758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (sscanf(dirent->d_name, "cpu%d", &cpu_nr) != 1) 4768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 4778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd path = stats_path + dirent->d_name + "/"; 4788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ret = op_read_int_from_file((path + "sample_lost_overflow"). 4798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd c_str(), 0); 4808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd closedir(dir); 4828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd done: 4847a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown if (ret > 0) { 4858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cerr << "WARNING! The OProfile kernel driver reports sample " 4868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << "buffer overflows." << endl; 4878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cerr << "Such overflows can result in incorrect sample attribution" 4888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << ", invalid sample" << endl 4898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << "files and other symptoms. " 4908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << "See the oprofiled.log for details." << endl; 4918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cerr << "You should adjust your sampling frequency to eliminate" 4928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << " (or at least minimize)" << endl 4938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << "these overflows." << endl; 4948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 4958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 4968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 4988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} // anonymous namespace 4998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddlist<string> profile_spec::generate_file_list(bool exclude_dependent, 5028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool exclude_cg) const 5038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{ 5048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd // FIXME: isn't remove_duplicates faster than doing this, then copy() ? 5058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd set<string> unique_files; 5068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string> sessions = filter_session(session, session_exclude); 5088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (sessions.empty()) { 5108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ostringstream os; 5118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd os << "No session given\n" 5128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << "included session was:\n"; 5138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd copy(session.begin(), session.end(), 5148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ostream_iterator<string>(os, "\n")); 5158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd os << "excluded session was:\n"; 5168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd copy(session_exclude.begin(), session_exclude.end(), 5178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ostream_iterator<string>(os, "\n")); 5188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd throw invalid_argument(os.str()); 5198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd bool found_file = false; 5228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string>::const_iterator cit = sessions.begin(); 5248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd vector<string>::const_iterator end = sessions.end(); 5258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (; cit != end; ++cit) { 5278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (cit->empty()) 5288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd continue; 5298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd string base_dir; 5318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd invalid_sample_file = false; 5328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if ((*cit)[0] != '.' && (*cit)[0] != '/') 5338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd base_dir = archive_path + op_samples_dir; 5348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd base_dir += *cit; 5358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd base_dir = op_realpath(base_dir); 5378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list<string> files; 5398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd create_file_list(files, base_dir, "*", true); 5408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!files.empty()) { 5428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd found_file = true; 5438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd warn_if_kern_buffs_overflow(base_dir + "/"); 5448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list<string>::const_iterator it = files.begin(); 5478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list<string>::const_iterator fend = files.end(); 5488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd for (; it != fend; ++it) { 5498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (valid_candidate(base_dir, *it, *this, 5508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd exclude_dependent, exclude_cg)) { 5518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd unique_files.insert(*it); 5528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (invalid_sample_file) { 5558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cerr << "Warning: Invalid sample files found in " 5568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << base_dir << endl; 5578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd cerr << "This problem can be caused by too high of a sampling rate." 5588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << endl; 5598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd if (!found_file) { 5638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd ostringstream os; 5648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd os << "No sample file found: try running opcontrol --dump\n" 5658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd << "or specify a session containing sample files\n"; 5668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd throw op_fatal_error(os.str()); 5678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd } 5688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd list<string> result; 5708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd copy(unique_files.begin(), unique_files.end(), back_inserter(result)); 5718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd 5728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd return result; 5738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd} 574