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

Todd Fiala tfiala at google.com
Mon Mar 3 17:05:29 PST 2014


So I tried this patch:

tfiala at ubuntu:~/lldb/git/llvm/tools/lldb/source/Plugins$ git diff
diff --git a/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp
b/source
index f2c1bab..72f8838 100644
--- a/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp
+++ b/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp
@@ -83,8 +83,10 @@ struct UserArea
 };

 #define DR_SIZE sizeof(UserArea::u_debugreg[0])
-#define DR_OFFSET(reg_index) \
-    (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
+
+// FIXME: remove the following code as soon as we get the UserArea
structure fi
+#define DR_OFFSET(reg_index) (0xFC + (reg_index * 4))
+// #define DR_OFFSET(reg_index)        (LLVM_EXTENSION offsetof(UserArea,
u_deb
 #define FPR_SIZE(reg) sizeof(((FPR_i386*)NULL)->reg)

 //---------------------------------------------------------------------------

But I'm still getting the assertion.  I did put an #error in the file to
make sure I wasn't somehow not building it.

I see where my wires crossed when reading the user.h header.

I'm working on a better fix (i.e. fixing it up to do what I had intended it
to do).

FWIW you can shut off assertions and what appears to happen is the
watchpoint code just fails to initialize (the reason it was running on my
end).

On your question re: copying the structure:
this code has to compile in places other than i386 Linux (i.e. we can debug
i386 Linux code on other hosts, that don't have the user.h available, or
have the wrong one available).




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

> 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
>



-- 
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/53ab2338/attachment.html>


More information about the lldb-dev mailing list