0

I'm building a library consisting of a class (MyTotp) that has an object as property (Profile). In the main test function I built a vector of Profile objects and a for loop which iterates through vector assigning the object to the MyTotp property and calculating the result. The program compiles correctly. When it is run the first loop is executed correctly but the second one raise a segmentation fault (core dump).

Debugging the program I noticed that the error appears after the second re-allocation of memory (required_size may change (and it does into the test) in each loop) for array uint8_t * secret as pointed into the code. I thought the re-allocation was the cause for the memory failure, but I can't exclude anything

Below the significant code...

MyTotp.h

class buzztotp {

public:
    [...]
    Profile profile;
    [...]
};

}

MyTotp.cpp

void MyTotp::getPaddedSecret(uint8_t * out) {
    uint8_t* secret = this->profile.getSecret();
    uint32_t secret_len = this->profile.getSecretLen();

    for (int i = 0; i < this->required_size; i++) {
        int index = i % secret_len;
        out[i] = secret[index];
    }

    delete[] secret; secret = NULL;
}

uint32_t MyTotp::generateTOTP() {

    this->preprocess(); //It calculates, according to profile properties, this->required_size
    uint8_t* secret = new uint8_t[this->required_size]; //Here the memory error while debugging
    this->getPaddedSecret(secret);

    [...]    

    delete[] secret; secret = NULL;

    return (...);
}

Profile.h

uint8_t* Profile::getSecret() const {
    uint8_t* out;
    out = new uint8_t[this->secret_len]; //#Edit1 - Error now here

    //memcpy(out, this->secret, this->secret_len*sizeof(uint8_t));
    std::copy(this->secret_vector.begin(), this->secret_vector.end(), out);

    return out;
}

main.cpp

int main(void) {
    currentDir();
    XmlResourceManager xmlresman;
    xmlresman.setFilename(std::string("...myfile.xml"));

    /*
    *  Here the vector<Profile> xmlresman::profiles is built as:
    *      
    *      Profile __profile;
    *      [...]
    *      this->profiles.push_back(__profile);
    */
    xmlresman.parseXml();

    for (unsigned int i = 0; i < xmlresman.profiles.size(); i++) {
        MyTotp mytotp;
        buzztotp.profile = xmlresman.profiles[i];

        try {
            std::cout << "TOTP: " << mytotp.generateTOTP() << std::endl;
        } catch (std::string str) {
            std::cerr << str << std::endl;
        }

        //mytotp.~mytotp();
    }

    return 0;
}

Any suggestions?


Edit1

I used two strategies (I can't figure the best out) for elaborating a uint8_t* by a function: generating/instantiating it into the parent block and passing it to the function as an argument OR returning a generated/instantiated pointer into the function itself. Running the debug again it seems the error is at the re-allocation of out into Profile::getSecret(). I'm starting to get confused about the behaviour of the program run.

The explicit destructor (mytotp) into the main loop was only a past try: it is a misprint, completely useless by now.


Edit2

Cancelling the explicit constructor seems to solve the problem.

Buzz
  • 1,102
  • 1
  • 9
  • 24
  • In `uint32_t MyTotp::generateTOTP() {` you have `delete[] secret; secret = NULL;` that could be a bug. What does `getPaddedSecret()` do with the pointer? – drescherjm Aug 12 '19 at 18:09
  • 2
    Why are you manually calling the destructor for `mytotp`? See [When is a C++ destructor called?](https://stackoverflow.com/questions/10081429/when-is-a-c-destructor-called) – 1201ProgramAlarm Aug 12 '19 at 18:09
  • Are you sure that it fails on the line `uint8_t* secret = new uint8_t[this->required_size];` I don't really see how that would fail there, even if the required size is zero - I assume that required_size is a member variable of unsigned integer type? What did you use to debug it and can you show your debug back trace? It feels like its more its to do with the pointer secret being de-referenced after its been deleted or something like this (i.e. most likely a bad memory de-reference). Without seeing the whole code of where the error is happening it will be alot of guesswork on our behalf... – code_fodder Aug 12 '19 at 18:27
  • The explicit destruction of `mytotp` is mysterious. You can’t have seen it in any examples. – molbdnilo Aug 12 '19 at 18:30
  • There is no reallocation in this code, only repeated allocation. Every time you call the function, there is a new `secret`, unrelated to any other `secret` that may have existed during a previous call. – molbdnilo Aug 12 '19 at 18:35
  • @drescherjm, the `secret = NULL` was added as a try in order to zero the pointer as well as the memory slots. `mytotp` destructor is explained in EDIT1 @code_fodder, `this->required_size` is never zero. I'm working to get you available the debug tracks. Thanks to all – Buzz Aug 12 '19 at 19:13
  • I was not questioning that part. The compiler should optimize out `secret = NULL` since it has no effect (local variable `secret` goes out of scope). I was questioning the deletion in the first part. However that depends on what you do with the pointer in `getPaddedSecret()`. With all of that said I think @1201ProgramAlarm has found the real bug. – drescherjm Aug 12 '19 at 19:14
  • Do yourself a favour and get rid of naked new/delete. Compare (amongst other guidelines) http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-newdelete and http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ri-raw and http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-use-ptr and http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r3-a-raw-pointer-a-t-is-non-owning. In your case use a `std::vector` instead. – Werner Henze Aug 12 '19 at 19:26
  • Ok, I really can't understand why, but deleting the explicit destructor the program seems to work fine. Can anyone explain me the point (or direct me on some explaination)? @WernerHenze, next step was that, but, sincerely, I couldn't accept to just change the method without understanding what was going wrong. For now, really thank's to all! – Buzz Aug 12 '19 at 19:41
  • With your `mytotp.~mytotp();` the destructor is called twice. Once on the manual call and also when `mytotp` goes out of scope (right after the manual call). – drescherjm Aug 12 '19 at 19:43
  • Ok, but why it crashes always into the second loop iteration and why the debug show the problem only in that particular method (`getPaddedSecret()`)? Isn't the destructor called twice also into the first iteration? – Buzz Aug 12 '19 at 19:46
  • You are probably corrupting the heap possibly due to a double delete. And a corrupt heap need not crash when the corruption occurs. – drescherjm Aug 12 '19 at 19:47
  • Ok, I got the point! Thank you – Buzz Aug 12 '19 at 19:49

0 Answers0