[lldb-dev] 32-bit linux IsWatchpointHit assertion failure due to WriteRegister

Todd Fiala tfiala at google.com
Mon Mar 3 16:26:47 PST 2014


Hah - okay, so as soon as I wrote that, it dawned on me that I always build
debug + asserts on 32-bit, until I hit the memory exhaustion on linkage, at
which point I flip to release + no asserts.  The working version above is
with release + no asserts.

I rebuilt with the same flags, except I used --enable-assertions.  I then
get your results:

tfiala at ubuntu:~/play/c++/sizeof$ ~/lldb/git/build-asserts/Release/bin/lldb
./sizeof
bash: /home/tfiala/lldb/git/build-asserts/Release/bin/lldb: No such file or
directory
tfiala at ubuntu:~/play/c++/sizeof$
~/lldb/git/build-asserts/Release+Asserts/bin/lldb ./sizeof
Current executable set to './sizeof' (i386).
(lldb) b sizeof.cpp:9
Breakpoint 1: where = sizeof`main + 75 at sizeof.cpp:10, address =
0x080484cb
(lldb) run
Process 18078 launching
lldb:
/home/tfiala/lldb/git/llvm/tools/lldb/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp:511:
virtual bool
RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t):
Assertion `false && "Could not initialize watchpoint registers"' failed.
Aborted (core dumped)
tfiala at ubuntu:~/play/c++/sizeof$

So, as a temporary work around I'll try your D register macro.  We'll want
to revisit and fix the register alignment since I'm sure other bits are off
due to that, but if that temporary work-around gets you going and doesn't
hit the assert, that's a decent place to start.

I am inclined to want to see some register tests added around this area so
we don't break this in the future.

Good catch, Matthew.



On Mon, Mar 3, 2014 at 3:35 PM, Todd Fiala <tfiala at google.com> wrote:

> The other relevant detail is I built lldb with these flags:
>
> ../llvm/configure --enable-cxx11 --prefix=`pwd`/../install
> --enable-optimized --disable-assertions
>
> So it is a release version of lldb.  I generally fail to build debug
> versions of lldb on 32-bit at the link phase due to exhausting memory.
>
>
> On Mon, Mar 3, 2014 at 3:30 PM, Todd Fiala <tfiala at google.com> wrote:
>
>> Hi Matthew,
>>
>> I tried again on a new Ubuntu 12.04 LTS x86 (32-bit) system built against
>> lldb svn r202726 with gcc 4.8.2 (built from source) and using the stock
>> Ubuntu 12.04 libedit-dev, lib-ncurses-dev, swig, python-dev:
>>
>> tfiala at ubuntu:~$ mkdir play
>> tfiala at ubuntu:~$ cd play
>> tfiala at ubuntu:~/play$ mkdir c++
>> tfiala at ubuntu:~/play$ cd c++
>> tfiala at ubuntu:~/play/c++$ ls
>> tfiala at ubuntu:~/play/c++$ mkdir sizeof
>> tfiala at ubuntu:~/play/c++$ cd sizeof
>> tfiala at ubuntu:~/play/c++/sizeof$ vim sizeof.cpp
>> ...
>> fiala at ubuntu:~/play/c++/sizeof$ cat sizeof.cpp
>> #include <stdio.h>
>>
>> int main(int argc, char **argv)
>> {
>> for (int i = 0; i < argc; ++i)
>>  {
>> printf("arg %d: %s\n", i, argv[i]);
>>  }
>>
>> printf("sizeof(short int): %u\n", sizeof(short int));
>>  printf("sizeof(int): %u\n", sizeof(int));
>> printf("sizeof(long): %u\n", sizeof(long));
>>
>> return 0;
>> }
>>
>> tfiala at ubuntu:~/play/c++/sizeof$ g++ --version
>> g++ (GCC) 4.8.2
>> Copyright (C) 2013 Free Software Foundation, Inc.
>> This is free software; see the source for copying conditions.  There is NO
>> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
>> PURPOSE.
>>
>> tfiala at ubuntu:~/play/c++/sizeof$ uname -a
>> Linux ubuntu 3.8.0-36-generic #52~precise1-Ubuntu SMP Mon Feb 3 21:56:56
>> UTC 2014 i686 i686 i386 GNU/Linux
>>
>> tfiala at ubuntu:~/play/c++/sizeof$ g++ -O0 -g -Wall -o sizeof sizeof.cpp
>> tfiala at ubuntu:~/play/c++/sizeof$ ./sizeof
>> arg 0: ./sizeof
>> sizeof(short int): 2
>> sizeof(int): 4
>> sizeof(long): 4
>>
>> tfiala at ubuntu:~/play/c++/sizeof$ ~/lldb/git/build/Release/bin/lldb
>> ./sizeof
>> Current executable set to './sizeof' (i386).
>> (lldb) b sizeof.cpp:9
>> Breakpoint 1: where = sizeof`main + 75 at sizeof.cpp:10, address =
>> 0x080484cb
>> (lldb) run
>> Process 20068 launching
>> Process 20068 stopped
>> * thread #1: tid = 20068, 0xb77ca1d0, name = 'sizeof', stop reason = trace
>>     frame #0: 0xb77ca1d0
>> -> 0xb77ca1d0:  movl   %esp, %eax
>>    0xb77ca1d2:  calll  0xb77cdc80
>>    0xb77ca1d7:  movl   %eax, %edi
>>    0xb77ca1d9:  calll  0xb77ca1c0
>> Process 20068 launched: './sizeof' (i386)
>> arg 0: ./sizeof
>> Process 20068 stopped
>> * thread #1: tid = 20068, 0x080484cb sizeof`main(argc=1, argv=0xbf8babf4)
>> + 75 at sizeof.cpp:10, name = 'sizeof', stop reason = breakpoint 1.1
>>     frame #0: 0x080484cb sizeof`main(argc=1, argv=0xbf8babf4) + 75 at
>> sizeof.cpp:10
>>    7   printf("arg %d: %s\n", i, argv[i]);
>>    8   }
>>    9
>> -> 10   printf("sizeof(short int): %u\n", sizeof(short int));
>>    11   printf("sizeof(int): %u\n", sizeof(int));
>>    12   printf("sizeof(long): %u\n", sizeof(long));
>>    13
>> (lldb) n
>> (lldb) sizeof(short int): 2
>> Process 20068 stopped
>> * thread #1: tid = 20068, 0x080484df sizeof`main(argc=1, argv=0xbf8babf4)
>> + 95 at sizeof.cpp:11, name = 'sizeof', stop reason = step over
>>     frame #0: 0x080484df sizeof`main(argc=1, argv=0xbf8babf4) + 95 at
>> sizeof.cpp:11
>>    8   }
>>    9
>>    10   printf("sizeof(short int): %u\n", sizeof(short int));
>> -> 11   printf("sizeof(int): %u\n", sizeof(int));
>>    12   printf("sizeof(long): %u\n", sizeof(long));
>>    13
>>    14   return 0;
>> n
>> (lldb) sizeof(int): 4
>> Process 20068 stopped
>> * thread #1: tid = 20068, 0x080484f3 sizeof`main(argc=1, argv=0xbf8babf4)
>> + 115 at sizeof.cpp:12, name = 'sizeof', stop reason = step over
>>     frame #0: 0x080484f3 sizeof`main(argc=1, argv=0xbf8babf4) + 115 at
>> sizeof.cpp:12
>>    9
>>    10   printf("sizeof(short int): %u\n", sizeof(short int));
>>    11   printf("sizeof(int): %u\n", sizeof(int));
>> -> 12   printf("sizeof(long): %u\n", sizeof(long));
>>    13
>>    14   return 0;
>>    15   }
>> n
>> (lldb) sizeof(long): 4
>> Process 20068 stopped
>> * thread #1: tid = 20068, 0x08048507 sizeof`main(argc=1, argv=0xbf8babf4)
>> + 135 at sizeof.cpp:14, name = 'sizeof', stop reason = step over
>>     frame #0: 0x08048507 sizeof`main(argc=1, argv=0xbf8babf4) + 135 at
>> sizeof.cpp:14
>>    11   printf("sizeof(int): %u\n", sizeof(int));
>>    12   printf("sizeof(long): %u\n", sizeof(long));
>>    13
>> -> 14   return 0;
>>    15   }
>> exit
>> Quitting LLDB will kill one or more processes. Do you really want to
>> proceed: [Y/n] y
>> tfiala at ubuntu:~/play/c++/sizeof$ file ./sizeof
>> ./sizeof: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
>> dynamically linked (uses shared libs), for GNU/Linux 2.6.24, not stripped
>>
>> tfiala at ubuntu:~/play/c++/sizeof$ pushd ~/lldb/git/llvm/tools/lldb/
>> ~/lldb/git/llvm/tools/lldb ~/play/c++/sizeof
>> tfiala at ubuntu:~/lldb/git/llvm/tools/lldb$ git log | head
>> commit f8af40b976db2738b132caf21aff5be785d84211
>> Author: Deepak Panickal <deepak at codeplay.com>
>> Date:   Mon Mar 3 15:53:37 2014 +0000
>>
>>     Check if the terminal is interactive and set the flags accordingly
>>
>>     git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@20272691177308-0d34-0410-b5e6-96231b3b80d8
>>
>> commit 92309dd86ab11faf8daa72f3f47c4d0ea5fb51e0
>> Author: Deepak Panickal <deepak at codeplay.com>
>> tfiala at ubuntu:~/lldb/git/llvm/tools/lldb$
>>
>> tfiala at ubuntu:~/lldb/git/llvm/tools/lldb$ git status
>> # On branch master
>> nothing to commit (working directory clean)
>>
>> ===================
>>
>> The only oddball thing I saw ws that it looks like some of the "prompt
>> before output" issues might have settled in when I started running the "n"
>> command.
>>
>> I've output my system version info (uname -a), the g++ version info (g++
>> --version), and the change list I'm synched to (using the git mirror at
>> http://llvm.org/git/lldb, synched to svn r202726).  I've also included
>> the test program I'm using.
>>
>> It would be great if you could essentially do these same steps on your
>> system so we can start seeing if and where we diverge on the same system.
>>  Also note my git branch is clean (this was an entirely new Ubuntu install).
>>
>> Thanks!
>>
>> -Todd
>>
>>
>> On Mon, Mar 3, 2014 at 8:47 AM, Todd Fiala <tfiala at google.com> wrote:
>>
>>> Hi Matthew,
>>>
>>> Thanks for the analysis.
>>>
>>>
>>> > #define DR_OFFSET(reg_index) \
>>> >    (0xFC + (reg_index * 4))
>>> > Can't we just use this in our lldb code?
>>>
>>> We could, but the fact that it is not lining up right on your side means
>>> all the parts between the misaligned bits and the DR registers are also
>>> broken.  So there's something deeper here going on.
>>>
>>> > As the fpregs and fpxregs structs are of differing sizes pushes the
>>> offsets of the dr registers out.
>>>
>>> I think you're referring to this part, right?
>>>
>>>  union
>>> +    {
>>> +        struct
>>> +        {
>>> +            uint64_t fip;   // Instruction Pointer
>>> +            uint64_t fdp;   // Data Pointer
>>> +        } x86_64;
>>> +        struct
>>> +        {
>>> +            uint32_t fioff;   // FPU IP Offset (fip)
>>> +            uint32_t fiseg;   // FPU IP Selector (fcs)
>>> +            uint32_t fooff;   // FPU Operand Pointer Offset (foo)
>>> +            uint32_t foseg;   // FPU Operand Pointer Selector (fos)
>>> +        } i386;
>>> +    } ptr;
>>>
>>> Both the x86_64 and i386 portion of the structure are unioned, and both
>>> are 128 bits wide.
>>>
>>> +    MMSReg   stmm[8];       // 8*16 bytes for each FP-reg = 128 bytes
>>> +    XMMReg   xmm[8];        // 8*16 bytes for each XMM-reg = 128 bytes
>>> +    uint32_t padding[56];
>>>
>>> These are different than the true x86_64 version to match the x86 32-bit
>>> size.
>>>
>>> The reason I changed them was to solve the original issue of the 32-bit
>>> lldb running against a 32-bit inferior trying to read the 64-bit register.
>>>  Your patch had added some code to say "when reading a 64-bit register
>>> value, really just return 32-bits".  But the reason it was trying to read
>>> 64-bits was because of the way the FPR_SIZE macro was defined.  I added a
>>> mechanism to allow it to be possibly defined ahead of time, which is what
>>> we now do in the case of the i386 register infos setup within the Linux
>>> RegisterContext i386 class here:
>>>
>>> +#define FPR_SIZE(reg) sizeof(((FPR_i386*)NULL)->reg)
>>>
>>> That, in turn, required that the proper elements be defined in the
>>> floating point save region.
>>>
>>>
>>> Today I'm going to try a few things:
>>>
>>> * build the 32-bit setup with configure/make.  This might expose
>>> different behavior on my 32-bit systems vs. the cmake/ninja builds I did
>>> last week.
>>>
>>> * add some logging during 32-bit register setup to dump the offsets of
>>> all the relevant parts.  I'm going to spit out what I'm getting on my end
>>> and would like you to do the same so we can see where we're getting
>>> different alignment.  This might end up boiling down to compiler flags
>>> (which might be exposed when I use configure/make, and might imply we need
>>> some #pragma/alignment decls).
>>>
>>> It would be great if you can confirm a few things just to make sure all
>>> my assumptions are right:
>>> * What OS are you using?  ('uname -a' data)
>>> * What compiler are you using? (compiler version string)
>>> * What hardware is this running on?
>>>
>>> Thanks Matthew!  We'll get this all straightened out.
>>>
>>>
>>>
>>> On Mon, Mar 3, 2014 at 6:02 AM, Matthew Gardiner <mg11 at csr.com> wrote:
>>>
>>>> Yes, my latest pain in 32-bit linux occurs due to the offset
>>>> calculations for dr6/7 being broken by the inclusion of the extended
>>>> floating point registers structure in "struct UserArea". I'm not really
>>>> sure what we are trying to model here, since, looking at sys/user.h, it's
>>>> the regular FP registers (user_fpregs_struct) which comprise the user area
>>>> not the extended ones (user_fpxregs_struct).
>>>>
>>>> I did try to fix this issue by reinstating the previous definition for
>>>> FPR_i386, i.e.
>>>>
>>>> struct FPR_i386
>>>> {
>>>>     int32_t cwd;
>>>>     int32_t swd;
>>>>     int32_t twd;
>>>>     int32_t fip;
>>>>     int32_t fcs;
>>>>     int32_t foo;
>>>>     int32_t fos;
>>>>     int32_t st_space [20];
>>>> };
>>>>
>>>> Unfortunately, this results in a world of pain, since the numerous
>>>> "DEFINE_FPR" invocations in RegisterInfos_i386.h rely on the elements
>>>> contained in user_fpxregs_struct.
>>>>
>>>> So, I solved this issue in a different (and in my opinion simpler) way
>>>> - by using the following macro to calculate the offset of a debug register
>>>> in the user:
>>>>
>>>> #define DR_OFFSET(reg_index) \
>>>>     (0xFC + (reg_index * 4))
>>>>
>>>> Can't we just use this in our lldb code?
>>>>
>>>> Why do we currently calculate the offsets with copied structures? Do we
>>>> actually use the structures as structures as well? This is a source of bugs.
>>>>
>>>> So I'll repeat what I hint to above...
>>>>
>>>> Can we remove the copied user/register structures and replace the
>>>> required offsets with integral constant definitions please?
>>>>
>>>> thanks
>>>> Matthew Gardiner
>>>>
>>>>
>>>>
>>>> Member of the CSR plc group of companies. CSR plc registered in England
>>>> and Wales, registered number 4187346, registered office Churchill House,
>>>> Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
>>>> More information can be found at www.csr.com. Keep up to date with CSR
>>>> on our technical blog, www.csr.com/blog, CSR people blog,
>>>> www.csr.com/people, YouTube, www.youtube.com/user/CSRplc, Facebook,
>>>> www.facebook.com/pages/CSR/191038434253534, or follow us on Twitter at
>>>> www.twitter.com/CSR_plc.
>>>> New for 2014, you can now access the wide range of products powered by
>>>> aptX at www.aptx.com.
>>>> _______________________________________________
>>>> lldb-dev mailing list
>>>> lldb-dev at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>>>
>>>
>>>
>>>
>>> --
>>>  Todd Fiala | Software Engineer |  tfiala at google.com |  650-943-3180
>>>
>>
>>
>>
>> --
>> Todd Fiala | Software Engineer |  tfiala at google.com |  650-943-3180
>>
>
>
>
> --
> Todd Fiala | Software Engineer |  tfiala at google.com |  650-943-3180
>



-- 
Todd Fiala | Software Engineer | tfiala at google.com | 650-943-3180
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140303/f2b718cc/attachment.html>


More information about the lldb-dev mailing list