[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