0

I want to overload new operator in a multi threaded environment and want to have thread id, function name and line number inside that. Is there any way to do this?

Anu
  • 47
  • 2
  • 2
    Until there is http://en.cppreference.com/w/cpp/experimental/source_location, you have to rely on MACRO. – Jarod42 Sep 08 '17 at 09:57
  • Possible duplicate of [C/C++ line number](https://stackoverflow.com/questions/2849832/c-c-line-number) – 463035818_is_not_an_ai Sep 08 '17 at 10:09
  • If you try to do that in the operator, you will always get the name and line number of where `operator new` is defined, not the place where it is called. – Bo Persson Sep 08 '17 at 10:19
  • Please **edit your question** to give much more details and *motivations* – Basile Starynkevitch Sep 08 '17 at 11:00
  • @Jarod42: Interesting. Seeing how that will be implemented in the library, I wonder how they'll make it work since the whole thing is declared `constexpr` and whenever I use `__FILE__` my compiler tells me "not a constant expression". – Damon Sep 08 '17 at 11:00
  • @Damon: Contrary to some classes of `std`, that will indeed require help of compiler (as it already helps for `__FUNC__`, `__LINE__`, for some traits...). – Jarod42 Sep 08 '17 at 11:33
  • Please [edit] your question to show [the code you have so far](http://whathaveyoutried.com). You should include at least an outline (but preferably a [mcve]) of the code that you are having problems with, then we can try to help with the specific problem. You should also read [ask]. – Toby Speight Sep 08 '17 at 14:55

2 Answers2

3

You can make a new operator new overload:

void * operator new(std::size_t count, const char* file, int line)
{
    // Do stuff
    // ...
    return ::operator new(count);
}

void * operator delete(void* p, const char* file, int line)
{
    // Do stuff
    // ...
    return ::operator delete(p);
}

// ... and [] versions ..

Then you can use placement syntax:

auto x = new (__FILE__, __LINE__) Foo;

And then you can add a macro:

#define TRACE_NEW new (__FILE__, __LINE__)

auto x = TRACE_NEW Foo;
molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • No, you are not overloading *placement new* but simply adding a global `operator new` and using that in `TRACE_NEW`. [placement new](http://en.cppreference.com/w/cpp/language/new) is something different like e.g. `void* p = mmap(`....`); auto x = new(p) Foo;` – Basile Starynkevitch Sep 08 '17 at 11:04
  • @BasileStarynkevitch Yeah, "placement new" was wrong. The Standard calls them "placement allocation functions" which is obviously not the same thing. Perhaps this wording is better. – molbdnilo Sep 08 '17 at 11:15
0

In general there is no way to do what you want (except of course by using macros like moldbnilo answered, or some future std::source_location)

However, if you are on a recent Linux system, and if all your code (and most of the libraries it is using, including libstdc++) is compiled with debug options, you might also consider Ian Taylor's libbacktrace (it is also used inside GCC) and use it inside your operator new implementation. That libbacktrace enables you to inspect call frames in your call stack using DWARF debug info.

You could then even have the source location of most functions in your call stack (notably the source location in the caller of your operator new).

Remember that you can compile some C++ code (using GCC or Clang) with both debug info (e.g. -g) and some optimization flags (e.g. -O1 or perhaps -O2); of course the debug info (in DWARF) would then be "fuzzy" but still mostly usable in practice.

BTW, perhaps you just need valgrind or some address sanitizing by compiling with -fsanitize=address instrumentation option (we don't know because your question is not motivated).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547