By Makogan


2019-05-15 16:32:20 8 Comments

Assume I have a class definition like this:

class A {
private:
    Field f;
public:
   /*A hundred methods all of which modify f*/

    m1();
    m2();
    ...
    m100();
}

We know before hand that all of these methods, if called, will modify f.

Assume you have a very spaghetti code base.

You need to find at runtime if and where f is actually modified.

You could use gdb, set a break point at every single method and see where execution stops and then unwind the stack to see which method called any of the m*() methods. This is very slow, prone to human error and not necessarily possible in a code base using emscripten, or where python calls the C++ binary after setting some state...

You could comment out all such methods and explore all places in the code where the compiler complains. This is, imho much worse than the prior, and it does do it at runtime, so it's harder to determine which method will ACTUALLY be called.

Similar as the above, you could mark all the above methods as deprecated, but it has more or less the same problems.

Does anyone have a suggestion on determining when and where the field actually gets modified?

3 comments

@Paul Evans 2019-05-15 16:40:12

Instead of using Field directly, use a wrapper that lets you know whenever f is modified. Something like (very crudely):

class FieldLogWhenModified
{
    Field data_;
public:
    FieldLogWhenModified(Field f) : data_(f) {}
    FieldLogWhenModified& operator=(const FieldLogWhenModified& new_f)
    {
        data_ = new_f.data_;
        // log or alert user in some way
        return *this;
    }

And/or perhaps:

    Field& operator=(const Field& new_data)
    {
        data_ = new_data;
        // log or alert user in some way
        return data_;
    }

@Makogan 2019-05-15 16:56:37

The problem with this is, if the field uses any other operator, now the wrapper must modify those operators as well. e.g, the compiler won;t know how to execute multiplication or subtraction with an integer wrapper. Although i like this approach a lot

@Paul Evans 2019-05-15 16:58:59

@Makogan Sure, the wrapper must support all operators/functions that Field does. But it simply passes those operations/functions to data_ and returns the result after logging the event.

@Makogan 2019-05-15 17:03:21

I know, as I said I like this approach a lot, I am just thinking it may be a bit cumbersome for data types that overload a lot of operators, like primitives or mathematical classes like matrices and vectors

@Lightness Races in Orbit 2019-05-15 17:22:22

It is. But then that's why you should have encapsulated accessors to begin with. If you didn't have 100 functions all modifying a primitive on their own then this wouldn't have been a problem ;)

@Makogan 2019-05-15 17:25:01

Blame the author of the code base, I am just debugging it : p

@Makogan 2019-05-15 17:33:37

I think you may have a typo, should it not be: data_ = new_f.f; ???

@Paul Evans 2019-05-15 22:31:26

@Makogan Yes indeed, now fixed. Thanks

@Paul Sanders 2019-05-15 16:39:15

On Intel (and perhaps some other) platforms, gdb supports the notion of watchpoints, i.e. a hardware breakpoint that fires when a particular memory location is written to.

The syntax for setting a watchpoint (without the square brackets) is:

watch -location [expr]

so in your case, something like:

watch -location my_object.f

Then run your code and note where it breaks into the debugger.

Documentation here and here

@CygnusX1 2019-05-15 16:38:20

Is it f of one particular object of class A?

If yes, you can set up a memory watch. It will break the program whenever memory at a given address (occupied by your field f) is changed.

It may make your program go slower, but it may be worth it in your case.

@Makogan 2019-05-15 16:53:47

No it is the f field in any arbitrary instance of class A

Related Questions

Sponsored Content

24 Answered Questions

[SOLVED] Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition

27 Answered Questions

[SOLVED] Program only crashes as release build -- how to debug?

  • 2008-10-09 07:18:42
  • Nik Reiman
  • 65126 View
  • 86 Score
  • 27 Answer
  • Tags:   c++ debugging

6 Answered Questions

[SOLVED] How to modify C++ code from user-input

3 Answered Questions

[SOLVED] What made i = i++ + 1; legal in C++17?

28 Answered Questions

[SOLVED] Is there a C++ gdb GUI for Linux?

3 Answered Questions

[SOLVED] How can one design a base class, so it knows about all the "derived" classes, at run time?

  • 2016-06-10 11:16:48
  • Kaizer Sozay
  • 407 View
  • 9 Score
  • 3 Answer
  • Tags:   c++

1 Answered Questions

[SOLVED] Calling Julia macro with runtime-dependent argument

1 Answered Questions

[SOLVED] Writing many void methods in a c++ class, and keeping track of variable changes

  • 2013-10-21 04:15:20
  • user2901669
  • 191 View
  • 0 Score
  • 1 Answer
  • Tags:   c++

2 Answered Questions

1 Answered Questions

[SOLVED] strategies to fix runtime errors

Sponsored Content