Достижение неожиданной точки останова obj c методом __Block_byref_object_copy_ - PullRequest
2 голосов
/ 13 июля 2020

Я использую lldb для отладки службы на основе obj c. несколько точек останова (которые установлены, были помещены в код, и я вижу, что одна из них достигается неожиданно в соответствии с трассировкой стека.

Метод, инкапсулирующий эту точку останова, не должен был вызываться, но я все еще вижу его в трассировке стека (file1.mm:97), хотя кажется, что код там не выполняется.

Я подозреваю, что obj c внутренний метод __Block_byref_object_copy_ отвечает за копирование блока кода, который включает в себя как вызывающий, так и вызываемый методы (MyClass из верхнего кадра в стеке и метод в file1.mm:97).

При копировании отладчик, вероятно, думает, что он достигает этой строки для выполнения и останавливается там, где на самом деле это только для копирования блока кода, который включает эти 2 метода.

Возможно, кто-нибудь может поддержать это утверждение или предоставить дополнительное объяснение, почему я получаю эту точку останова там, где она не должна возникать?

  * frame #0: 0x0000000107e03ce0 MyLib`::__Block_byref_object_copy_((null)=0x00007fda19a86b30, (null)=0x00007ffeea7f3bd0) at file1.mm:97:27
    frame #1: 0x00007fff7de6bb78 libsystem_blocks.dylib`_Block_object_assign + 325
    frame #2: 0x0000000107dd960a MyLib`::__copy_helper_block_ea8_32r((null)=0x00007fda19a86540, (null)=0x00007ffeea7f3ba8) at file2.mm:47:55
    frame #3: 0x00007fff7de6b9f3 libsystem_blocks.dylib`_Block_copy + 104
    frame #4: 0x00007fff7c64e1e8 libobjc.A.dylib`objc_setProperty_atomic_copy + 53
    frame #5: 0x00007fff5411d16b Foundation`-[NSXPCConnection _sendInvocation:orArguments:count:methodSignature:selector:withProxy:] + 1885
    frame #6: 0x00007fff54168508 Foundation`-[NSXPCConnection _sendSelector:withProxy:arg1:arg2:] + 125
    frame #7: 0x00007fff54168485 Foundation`_NSXPCDistantObjectSimpleMessageSend2 + 46
    frame #8: 0x0000000107e0520e MyLib`::-[MyClass func:withVar0:Var1:Var2:withError:](self=0x00007fda17c2cb50, _cmd="funcWithVar0:Var1:Var2:Var3:withError:", var0="aaa", var1=0x0000000000000000, var2="bbb", var3=0x00007fda17d41dd0, err=0x00007ffeea7f4258) at MyClass.mm:196:5

ОБНОВЛЕНИЕ:

благодаря комментариям ниже, если я установил точку останова в соответствии с упорядочивая файл и строку, он дает мне 3 места (!?)

набор точек останова --file myfile.mm --line 97

теперь, когда я перечисляю свои точки останова, он дает мне 2 точки останова, не относящиеся к фактическому методу, который обертывает файл, за исключением ожидаемой точки останова.

  3.2: where = my class`::__Block_byref_object_copy_() + 16 at myfile:97:27, address = 0x0000000107e03ce0, unresolved, hit count = 0 
  3.3: where = myclass `::__Block_byref_object_dispose_() + 16 at myfile:97:27, address = 0x0000000107e03d40, unresolved, hit count = 0 

1 Ответ

0 голосов
/ 14 июля 2020

Не совсем ответ, скорее иллюстрация ...

unsigned fn ( void )
{
    return 3;    // Set bp here and see what happens
}

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        // insert code here...
        NSLog(@"Hello, World!");
        unsigned int x = 0;

        x = 1;
        x = 2;
        x = 3;

        if ( x >= 0 )
        {
            switch ( 5 )
            {
                case 1 : x = 4; break;
                case 2 : x = 4; break;   // Set bp here - it will trigger!!!!
                case 3 : x = 4; break;
                case 4 : x = 4; break;
                case 5 : x = 4; break;   // Set bp here and see what happens
                case 6 : x = 4; break;
                case 7 : x = 4; break;
                default : x = 4; break;
                    
            }
        }

        __block unsigned y;

        void ( ^ b1 )( void ) = ^ {

            y = fn();

        };

        void ( ^ b2 )( void ) = ^ {

            b1();

        };

        if ( YES )
        {
            b2();
        }

        NSLog ( @"x = %u y = %u", x, y );
    }

    return 0;
}

Не вдаваясь в подробности, обратите внимание, что большая часть приведенного выше кода будет оптимизирована. Компилятор будет агрессивно оптимизировать for циклы и switches и будет оптимизировать лишние присваивания и проверки (например, x> = 0 для беззнакового x). Выше даже блоки становятся встроенными, и в итоге вы получаете очень странное поведение. Я думаю, что блоки здесь имеют отношение к вашей конкретной проблеме c?

Если вы оптимизируете, то первая точка останова, указанная в коде, не срабатывает, поскольку все блоки становятся встроенными (я думаю, как я не смотрел при разборке). Точно так же срабатывает третий, но из-за оптимизации в самых странных местах. На самом деле, большая часть кода сводится к одному назначению, и компилятор действительно не знает, где его закрепить, поэтому при срабатывании этого bp создается впечатление, что он находится в самом странном и наиболее изолированном месте из возможных.

Наконец, сработает даже второй (!!!). Этот код никогда не должен выполняться, но поскольку он все рушится из-за оптимизации, вы даже можете заставить его срабатывать.

Так что я не буду слишком озадачен тем, что запускает ваш bp ...

Я имею в виду Выше я только что доказал, что 2 == 5, если серьезно относиться к bp. И это даже не переменная, а постоянная 2 == 5 !!! Довольно забавно ...

...