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

Todd Fiala tfiala at google.com
Mon Mar 3 15:35:05 PST 2014


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140303/581dc2b3/attachment.html>


More information about the lldb-dev mailing list