diff options
author | Wenji Huang <wenji.huang@oracle.com> | 2010-02-03 10:21:24 +0800 |
---|---|---|
committer | Wenji Huang <wenji.huang@oracle.com> | 2010-02-03 10:21:24 +0800 |
commit | 0d1ad607311857dc0b4666ce8a84c1a59c615ab9 (patch) | |
tree | 57aaf3d3eadbe75cd22be6e073c8d17f3801392f | |
parent | fff4e6c6e4bb5bd1046164d697872f0bc1a48f4c (diff) | |
download | systemtap-steved-0d1ad607311857dc0b4666ce8a84c1a59c615ab9.tar.gz systemtap-steved-0d1ad607311857dc0b4666ce8a84c1a59c615ab9.tar.xz systemtap-steved-0d1ad607311857dc0b4666ce8a84c1a59c615ab9.zip |
PR9931: generate log to help diagnosing occasional cache hash collisions
Ideas from Frank Ch. Eigler:
- extending the hash.add() function to pass names along with the
hash-mix values, so that class hash can internally track the
hash-report string
- storing the reports themselves in the cache, beside the .ko / .c
files, and changing the cache-size-limit logic to delete
these .txt files upon garbage collection
* hash.h : New member parm_stream.
* hash.cxx (get_parms): New function to convert parms stream to string.
(hash::add): Aggregrate parms stream.
(create_hash_log): New function to log hash operation.
(find_*_hash): Log hash at the end of function.
* cache.cxx (clean_cache): Remove log when cache reaches limitation.
-rw-r--r-- | cache.cxx | 20 | ||||
-rw-r--r-- | hash.cxx | 33 | ||||
-rw-r--r-- | hash.h | 5 |
3 files changed, 58 insertions, 0 deletions
@@ -282,6 +282,22 @@ clean_cache(systemtap_session& s) globfree(&cache_glob); + // grab info for each staphash log file (.log) + glob_str = s.cache_path + "/*/*.log"; + glob(glob_str.c_str(), 0, NULL, &cache_glob); + for (unsigned int i = 0; i < cache_glob.gl_pathc; i++) + { + string cache_ent_path = cache_glob.gl_pathv[i]; + struct cache_ent_info cur_info(cache_ent_path, false); + if (cur_info.size != 0 && cur_info.weight != 0) + { + cache_size_b += cur_info.size; + cache_contents.insert(cur_info); + } + } + + globfree(&cache_glob); + set<struct cache_ent_info>::iterator i; unsigned long r_cache_size = cache_size_b; string removed_dirs = ""; @@ -344,9 +360,11 @@ cache_ent_info::cache_ent_info(const string& path, bool is_module): string mod_path = path + ".ko"; string modsgn_path = path + ".ko.sgn"; string source_path = path + ".c"; + string hash_path = path + ".log"; size = get_file_size(mod_path) + get_file_size(modsgn_path); + get_file_size(source_path); + + get_file_size(hash_path); weight = get_file_weight(mod_path); } else @@ -365,9 +383,11 @@ cache_ent_info::unlink() const string mod_path = path + ".ko"; string modsgn_path = path + ".ko.sgn"; string source_path = path + ".c"; + string hash_path = path + ".log"; ::unlink(mod_path.c_str()); ::unlink(modsgn_path.c_str()); ::unlink(source_path.c_str()); + ::unlink(hash_path.c_str()); } else ::unlink(path.c_str()); @@ -43,6 +43,7 @@ hash::start() void hash::add(const unsigned char *buffer, size_t size) { + parm_stream << "," << buffer; mdfour_update(&md4, buffer, size); } @@ -60,6 +61,16 @@ hash::add_file(const std::string& filename) add(st.st_mtime); } +string +hash::get_parms() +{ + string parms_str = parm_stream.str(); + + parm_stream.clear(); + if (!parms_str.empty()) + parms_str.erase(parms_str.begin()); // skip leading "," + return parms_str; +} void hash::result(string& r) @@ -78,6 +89,20 @@ hash::result(string& r) r = rstream.str(); } +void create_hash_log(const string &type_str, const string &parms, const string &result, const string &hash_log_path) +{ + ofstream log_file; + time_t rawtime; + time ( &rawtime ); + string time_str(ctime (&rawtime)); + + log_file.open(hash_log_path.c_str()); + log_file << "[" << time_str.substr(0,time_str.length()-1); // erase terminated '\n' + log_file << "]" << type_str; + log_file << ": " << parms << endl; + log_file << "result:" << result << endl; + log_file.close(); +} static void get_base_hash (systemtap_session& s, hash& h) @@ -229,6 +254,8 @@ find_script_hash (systemtap_session& s, const string& script, const hash &base) // Update C source name with new module_name. s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c"; + create_hash_log(string("script_hash"), h.get_parms(), result, + hashdir + "/" + s.module_name + "_hash.log"); } @@ -249,6 +276,8 @@ find_stapconf_hash (systemtap_session& s, const hash& base) s.stapconf_name = "stapconf_" + result + ".h"; s.stapconf_path = hashdir + "/" + s.stapconf_name; + create_hash_log(string("stapconf_hash"), h.get_parms(), result, + hashdir + "/stapconf_" + result + "_hash.log"); } @@ -282,6 +311,8 @@ find_tracequery_hash (systemtap_session& s, const vector<string>& headers) if (!create_hashdir(s, result, hashdir)) return ""; + create_hash_log(string("tracequery_hash"), h.get_parms(), result, + hashdir + "/tracequery_" + result + "_hash.log"); return hashdir + "/tracequery_" + result + ".ko"; } @@ -306,6 +337,8 @@ find_typequery_hash (systemtap_session& s, const string& name) if (!create_hashdir(s, result, hashdir)) return ""; + create_hash_log(string("typequery_hash"), h.get_parms(), result, + hashdir + "/typequery_" + result + "_hash.log"); return hashdir + "/typequery_" + result + (name[0] == 'k' ? ".ko" : ".so"); } @@ -1,5 +1,7 @@ #include <string> #include <vector> +#include <sstream> +#include <fstream> extern "C" { #include <string.h> @@ -13,9 +15,11 @@ class hash { private: struct mdfour md4; + std::ostringstream parm_stream; public: hash() { start(); } + hash(const hash &base) { start(); parm_stream << base.parm_stream.str();} void start(); @@ -34,6 +38,7 @@ public: void add_file(const std::string& filename); void result(std::string& r); + std::string get_parms(); }; void find_hash (systemtap_session& s, const std::string& script); |