 Chromium Code Reviews
 Chromium Code Reviews Issue 8000001:
  Catch some "easy to spot" double frees in TCMalloc  (Closed) 
  Base URL: svn://chrome-svn/chrome/trunk/src/
    
  
    Issue 8000001:
  Catch some "easy to spot" double frees in TCMalloc  (Closed) 
  Base URL: svn://chrome-svn/chrome/trunk/src/| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2011, Google Inc. | 1 // Copyright (c) 2011, Google Inc. | 
| 2 // All rights reserved. | 2 // All rights reserved. | 
| 3 // | 3 // | 
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without | 
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are | 
| 6 // met: | 6 // met: | 
| 7 // | 7 // | 
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright | 
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. | 
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 // the former head's |next| pointer. If the list is doubly linked, the | 57 // the former head's |next| pointer. If the list is doubly linked, the | 
| 58 // new head |previous| pointer gets changed from pointing to the former | 58 // new head |previous| pointer gets changed from pointing to the former | 
| 59 // head to NULL. | 59 // head to NULL. | 
| 60 | 60 | 
| 61 | 61 | 
| 62 #ifdef TCMALLOC_USE_DOUBLYLINKED_FREELIST | 62 #ifdef TCMALLOC_USE_DOUBLYLINKED_FREELIST | 
| 63 | 63 | 
| 64 #include <stddef.h> | 64 #include <stddef.h> | 
| 65 #include "internal_logging.h" //for ASSERT | 65 #include "internal_logging.h" //for ASSERT | 
| 66 | 66 | 
| 67 // TODO(jar): We should use C++ rather than a macro here. | |
| 67 #define MEMORY_CHECK(v1, v2) \ | 68 #define MEMORY_CHECK(v1, v2) \ | 
| 68 if (v1 != v2) CRASH("Memory corruption detected.\n") | 69 if (v1 != v2) CRASH("Memory corruption detected.\n") | 
| 69 | 70 | 
| 70 namespace { | 71 namespace { | 
| 72 void EnusreNonLoop(void* node, void* next) { | |
| 
jschuh
2011/09/28 23:13:11
I think you meant EnsureNonLoop.
 
jar (doing other things)
2011/09/29 22:30:57
Done.
 | |
| 73 // We only have time to do minimal checking. We don't traverse the list, but | |
| 74 // only look for an immediate loop (cycle back to ourself). | |
| 75 if (node != next) return; | |
| 76 CRASH("Circular loop in list detected: %p\n", next); | |
| 77 } | |
| 78 | |
| 71 // Returns value of the |previous| pointer w/out running a sanity | 79 // Returns value of the |previous| pointer w/out running a sanity | 
| 72 // check. | 80 // check. | 
| 73 inline void *FL_Previous_No_Check(void *t) { | 81 inline void *FL_Previous_No_Check(void *t) { | 
| 74 return reinterpret_cast<void**>(t)[1]; | 82 return reinterpret_cast<void**>(t)[1]; | 
| 75 } | 83 } | 
| 76 | 84 | 
| 77 // Returns value of the |next| pointer w/out running a sanity check. | 85 // Returns value of the |next| pointer w/out running a sanity check. | 
| 78 inline void *FL_Next_No_Check(void *t) { | 86 inline void *FL_Next_No_Check(void *t) { | 
| 79 return reinterpret_cast<void**>(t)[0]; | 87 return reinterpret_cast<void**>(t)[0]; | 
| 80 } | 88 } | 
| 81 | 89 | 
| 82 void *FL_Previous(void *t) { | 90 void *FL_Previous(void *t) { | 
| 83 void *previous = FL_Previous_No_Check(t); | 91 void *previous = FL_Previous_No_Check(t); | 
| 84 if (previous) { | 92 if (previous) { | 
| 85 MEMORY_CHECK(FL_Next_No_Check(previous), t); | 93 MEMORY_CHECK(FL_Next_No_Check(previous), t); | 
| 86 } | 94 } | 
| 87 return previous; | 95 return previous; | 
| 88 } | 96 } | 
| 89 | 97 | 
| 90 inline void FL_SetPrevious(void *t, void *n) { | 98 inline void FL_SetPrevious(void *t, void *n) { | 
| 99 EnusreNonLoop(t, n); | |
| 91 reinterpret_cast<void**>(t)[1] = n; | 100 reinterpret_cast<void**>(t)[1] = n; | 
| 92 } | 101 } | 
| 93 | 102 | 
| 94 inline void FL_SetNext(void *t, void *n) { | 103 inline void FL_SetNext(void *t, void *n) { | 
| 104 EnusreNonLoop(t, n); | |
| 95 reinterpret_cast<void**>(t)[0] = n; | 105 reinterpret_cast<void**>(t)[0] = n; | 
| 96 } | 106 } | 
| 97 | 107 | 
| 98 } // namespace | 108 } // namespace | 
| 99 | 109 | 
| 100 namespace tcmalloc { | 110 namespace tcmalloc { | 
| 101 | 111 | 
| 102 void *FL_Next(void *t) { | 112 void *FL_Next(void *t) { | 
| 103 void *next = FL_Next_No_Check(t); | 113 void *next = FL_Next_No_Check(t); | 
| 104 if (next) { | 114 if (next) { | 
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 | 220 | 
| 211 namespace { | 221 namespace { | 
| 212 | 222 | 
| 213 inline void FL_SetNext(void *t, void *n) { | 223 inline void FL_SetNext(void *t, void *n) { | 
| 214 tcmalloc::SLL_SetNext(t,n); | 224 tcmalloc::SLL_SetNext(t,n); | 
| 215 } | 225 } | 
| 216 | 226 | 
| 217 } | 227 } | 
| 218 | 228 | 
| 219 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST | 229 #endif // TCMALLOC_USE_DOUBLYLINKED_FREELIST | 
| OLD | NEW |