Jump to content
  • Advertisement
Sign in to follow this  
hobbydev

[Debugger] Determine a breakpoint line is valid

This topic is 577 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys,

I would like to know if a breakpoint set on certain line is valid before it actually being hit.

I'm currently do some debugging implementation. e.g. user set the breakpoints and after launching the script, some of the invalid breakpoints shown as invalid in the GUI (i.e. they are not inside of any functions).

I have studied the official debugger add-on and it has CheckBreakPoint function which checks the breakpoints when the code runs to the line, however, I really want to know if this line is valid or should be moved to some near line BEFORE it gets hit.

 

Do you have any ideas?

Cheers!

Edited by hobbydev

Share this post


Link to post
Share on other sites
Advertisement

Hi Andreas,

I've tried the approach, and it works well for functions.

However, it's not working for ObjectType methods or global variables.

(e.g. Test::method() or string g_str = getDefaultString(); of script.as from asrun sample)

If there is answer, please let me know.

Thank you very much! :ph34r:

Edited by hobbydev

Share this post


Link to post
Share on other sites

For global variables there is currently no interface for obtaining the position where the variable has been declared. I'll see if I can add this for the upcoming release (2.32.0). If you don't want to wait until I can provide code changes, you ought to be able to do it yourself with a bit of customization of the library (look for the class asCGlobalProperty and then in the member initFunc (type asCScriptFunction) you'll find the declaredAt and scriptSectionIdx that hold the location where the code was declared)

 

As for class methods it should be working already. You'll need to enumerate the types to find each of the declared classes, and then for each of the classes you enumerate the methods and factories.

 

If you're still having trouble, please show me what you've done and the error you're getting so I can investigate it in more detail.

Share this post


Link to post
Share on other sites

Hi Andreas,

It's encouraging to see your reply.

I'm tring the member methods and factories but they failed.

 

I put my test code into the function body of

void CDebugger::LineCallback(asIScriptContext *ctx)

since I don't know if the running context is dependent.

 

You can test line 38 of script.as, this is the method() function of class Test. In this test, the FindNextLineWithCode function will always fail due to the condition failure

scriptData == 0

in FindNextLineWithCode function.

 

Here is my testing code

    int currentLine = ctx->GetLineNumber(0, 0, &file);
    if (currentLine == 38)
    {
        int i = 0; // put a breakpoint here test, line 38 is "void Test::method()"
    }

    std::cout << "current line: " << currentLine << std::endl;

    asIScriptModule* module = engine_->GetModule("script");
    if (!module)
        return;

    // all functions from the object types
    std::vector<asIScriptFunction*> allFunctions;

    // for each object type
    for (size_t i = 0, objectTypeCount = module->GetObjectTypeCount(); i < objectTypeCount; ++i)
    {
        asITypeInfo* objectType = module->GetObjectTypeByIndex(i);
        assert(objectType);
        if (!objectType)
            continue;

        // member methods
        for (size_t j = 0, methodCount = objectType->GetMethodCount(); j < methodCount; ++j)
        {
            asIScriptFunction* func = objectType->GetMethodByIndex(j);
            assert(func);
            if (func)
            {
                std::cout << objectType->GetName() << "::" << func->GetName() << std::endl;
                allFunctions.push_back(func);
            }
        }

        // factories
        for (size_t j = 0, factoryCount = objectType->GetFactoryCount(); j < factoryCount; ++j)
        {
            asIScriptFunction* func = objectType->GetFactoryByIndex(j);
            if (func)
            {
                std::cout << objectType->GetName() << "::" << func->GetName() << std::endl;
                allFunctions.push_back(func);
            }
        }
    }

    // check every functions
    for (size_t i = 0; i < allFunctions.size(); ++i)
    {
        asIScriptFunction* func = allFunctions[i];
        assert(func);

        std::cout << func->GetName();
        
        static int lineNum = 38;
        int actualLine = func->FindNextLineWithCode(lineNum);

        std::cout << ", line=" << actualLine << std::endl;  // *** in my test, actualLine is always -1 ***
    }

Cheers!

Edited by hobbydev

Share this post


Link to post
Share on other sites
For global variables there is currently no interface for obtaining the position where the variable has been declared. I'll see if I can add this for the upcoming release (2.32.0). If you don't want to wait until I can provide code changes, you ought to be able to do it yourself with a bit of customization of the library (look for the class asCGlobalProperty and then in the member initFunc (type asCScriptFunction) you'll find the declaredAt and scriptSectionIdx that hold the location where the code was declared)

I had a quick test for the way you suggested, it works!

Please have a look at class methods and factories and my testing code as my previous reply.

 

 

As for class methods it should be working already. You'll need to enumerate the types to find each of the declared classes, and then for each of the classes you enumerate the methods and factories.

 

Thank you very much!

Edited by hobbydev

Share this post


Link to post
Share on other sites

For GetMethodByIndex you need to tell angelscript that you want the non-virtual function so you get the actual implementation: "GetMethodByIndex(j, false)"

 

The factory will be a bit trickier, just as for global variables there is currently no interface available to do what you want. The function that you get with GetFactory is a stub function that allocate the memory for the object and then internally calls the real constructor that performs the actual initialization. You need to get to the actual constructor so you can check the valid lines for breakpoints. 

I can think of two possible ways at the moment:

1. find the matching constructor in the asCObjectType::beh::constructors array. The index for the constructor in the array will be the same index where the factory is stored in asCObjectType::beh::factories array.

2. use the JIT interface to enumerate the bytecode for the factory until you find the asBC_ALLOC instruction that will hold the function id of the constructor.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!