I have a Mutex object whose lock function is mysteriously being called many times during certain conditions/times (it keeps track via an internal per thread counter and reports the total number of occurrences on a fixed frequency). It would be neat if I could add a check in the code where, say, every 100 or so calls in a fixed time bucket it logs who called it to get a better idea of who might be at fault. I think this should be possible via some stack trace thing but I'm not sure where to start or what to reference. Is there a simple way to go about this?
-
can you not just set a breakpoint in your debugger? – pippin1289 Jun 16 '14 at 14:42
-
[dtrace?](http://en.wikipedia.org/wiki/DTrace) – jsantander Jun 16 '14 at 14:43
-
I could but it's difficult/inconvenient to stop this application when it is already running and logging would be less intrusive – Palace Chan Jun 16 '14 at 14:43
-
Can't you just attach gdb to a process an examine functions on the stack? – mlt Jun 16 '14 at 14:48
-
1You could possibly add a parameter to the lock function and have each call site pass its own identifying parameter, e.g. an int. – molbdnilo Jun 16 '14 at 14:49
1 Answers
This might be one of the few times I recommend a macro.
Change the name of the function being called to a slight mangling of the original, such as Mutex::get
to Mutex::get_with_mapping
and add an extra parameter to take a string constant for location information.
Write a macro to wrap the old function name around a call to the new function placing the preprocessor token for the current function in the macro:
#define get() get_with_mapping(__func__)
Place this macro at the bottom of the header file of the Mutex object, so that it doesn't mess with the definition of the Mutex object. Hope that this macro doesn't mangle anything it isn't supposed to in source files that include it.
Modify the get (now get_with_mapping) function to keep a record of all the locations passed into it. You could also add file name and line number to the signature.

- 7,301
- 2
- 16
- 23
-
This actually gives me a compiler error like this: error: expected ',' or '...' before '__FUNCTION__' in #define funcA() funcB(__FUNCTION__) (same error with __func__) - am I missing something? – Palace Chan Jun 16 '14 at 15:28
-
@PalaceChan The preprocessor symbol for the current function is "`__func__`", with two underscores on each side. Did you use that? – John Jun 16 '14 at 15:32
-
Yea - it should work though it keeps saying "expected identifier before 'X' when I say #define funcA() funcB(X). (X is two underscores, func, and two underscores). - Do i need to quote anything? I think what's happening is it is replacing the signature of get with mapping_get and it is missing the identifier – Palace Chan Jun 16 '14 at 15:36
-
What compiler (and version) are you using? What is the exact text of the error, including line number? Is the error at the definition or a replacement location ("invocation"). Don't define the macro `get()` at the top of a header before the class definition that includes a declaration of a member something_get(). Define this macro after the class definition, at the bottom of the header. – John Jun 16 '14 at 15:42
-
@PalaceChan I think leaving get at the end of the function name will cause problems everywhere. I changed it to `get_with_mapping` in the answer. – John Jun 16 '14 at 16:02
-
Moving it the bottom worked! Thanks. The one concern I'm left with using this approach is that it could dangerously replace any usage of a function called 'get' in this example with an overloaded one. – Palace Chan Jun 16 '14 at 16:02
-
Macros are like fire: very powerful and very dangerous. Use them wisely, with proper protections, in their proper places. "Only you can prevent forest fires." – John Jun 16 '14 at 16:06
-
1I'd say that defining a `get` macro in a widely used mutex class is pure insanity. I'd at least call it `get_mutex` to limit the destruction you will achieve through clashes with other code. Alternatively, don't even bother with a macro. Simply manually type `Mutex::get(__func__)` at each call site. Surely it's not *that much* of an inconvenience, and it makes it very obvious what's going on. – Kuba hasn't forgotten Monica Jun 16 '14 at 16:09