alias.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_DEBUG_ALIAS_H_
  5. #define BASE_DEBUG_ALIAS_H_
  6. #include <stddef.h>
  7. #include "base/base_export.h"
  8. namespace base {
  9. namespace debug {
  10. // Make the optimizer think that |var| is aliased. This can be used to inhibit
  11. // three different kinds of optimizations:
  12. //
  13. // Case #1: Prevent a local variable from being optimized out if it would not
  14. // otherwise be live at the point of a potential crash. This can only be done
  15. // with local variables, not globals, object members, or function return values
  16. // - these must be copied to locals if you want to ensure they are recorded in
  17. // crash dumps. Function arguments are fine to use since the
  18. // base::debug::Alias() call on them will make sure they are copied to the stack
  19. // even if they were passed in a register. Note that if the local variable is a
  20. // pointer then its value will be retained but the memory that it points to will
  21. // probably not be saved in the crash dump - by default only stack memory is
  22. // saved. Therefore the aliasing technique is usually only worthwhile with
  23. // non-pointer variables. If you have a pointer to an object and you want to
  24. // retain the object's state you need to copy the object or its fields to local
  25. // variables.
  26. //
  27. // Example usage:
  28. // int last_error = err_;
  29. // base::debug::Alias(&last_error);
  30. // DEBUG_ALIAS_FOR_CSTR(name_copy, p->name, 16);
  31. // CHECK(false);
  32. //
  33. // Case #2: Prevent a tail call into a function. This is useful to make sure the
  34. // function containing the call to base::debug::Alias() will be present in the
  35. // call stack. In this case there is no memory that needs to be on
  36. // the stack so we can use nullptr. The call to base::debug::Alias() needs to
  37. // happen after the call that is suspected to be tail called. Note: This
  38. // technique will prevent tail calls at the specific call site only. To prevent
  39. // them for all invocations of a function look at NOT_TAIL_CALLED.
  40. //
  41. // Example usage:
  42. // NOINLINE void Foo(){
  43. // ... code ...
  44. //
  45. // Bar();
  46. // base::debug::Alias(nullptr);
  47. // }
  48. //
  49. // Case #3: Prevent code folding of a non-unique function. Code folding can
  50. // cause the same address to be assigned to different functions if they are
  51. // identical. If finding the precise signature of a function in the call-stack
  52. // is important and it's suspected the function is identical to other functions
  53. // it can be made unique using NO_CODE_FOLDING which is a wrapper around
  54. // base::debug::Alias();
  55. //
  56. // Example usage:
  57. // NOINLINE void Foo(){
  58. // NO_CODE_FOLDING();
  59. // Bar();
  60. // }
  61. //
  62. // Finally please note that these effects compound. This means that saving a
  63. // stack variable (case #1) using base::debug::Alias() will also inhibit
  64. // tail calls for calls in earlier lines and prevent code folding.
  65. void BASE_EXPORT Alias(const void* var);
  66. } // namespace debug
  67. BASE_EXPORT size_t strlcpy(char* dst, const char* src, size_t dst_size);
  68. } // namespace base
  69. // Convenience macro that copies the null-terminated string from |c_str| into a
  70. // stack-allocated char array named |var_name| that holds up to |char_count|
  71. // characters and should be preserved in memory dumps.
  72. #define DEBUG_ALIAS_FOR_CSTR(var_name, c_str, char_count) \
  73. char var_name[char_count]; \
  74. ::base::strlcpy(var_name, (c_str), sizeof(var_name)); \
  75. ::base::debug::Alias(var_name);
  76. // Code folding is a linker optimization whereby the linker identifies functions
  77. // that are bit-identical and overlays them. This saves space but it leads to
  78. // confusing call stacks because multiple symbols are at the same address and
  79. // it is unpredictable which one will be displayed. Disabling of code folding is
  80. // particularly useful when function names are used as signatures in crashes.
  81. // This macro doesn't guarantee that code folding will be prevented but it
  82. // greatly reduces the odds and always prevents it within one source file.
  83. // If using in a function that terminates the process it is safest to put the
  84. // NO_CODE_FOLDING macro at the top of the function.
  85. // Use like:
  86. // void FooBarFailure(size_t size) { NO_CODE_FOLDING(); OOM_CRASH(size); }
  87. #define NO_CODE_FOLDING() \
  88. const int line_number = __LINE__; \
  89. base::debug::Alias(&line_number)
  90. #endif // BASE_DEBUG_ALIAS_H_