32-bit linux IsWatchpointHit assertion failure due to WriteRegister

Hi folks

I've synced with the head of the tree this morning and rebuilt and I'm seeing another assertion failure impacting my 32-bit linux experience. Running my test app looks like this:

$ lldb hello
Current executable set to 'hello' (i386).
(lldb) log enable linux ptrace
(lldb) run
operation ptrace(PTRACE_SETOPTIONS, 8832, (nil), 0x58, 0)=0 called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 1456
operation ptrace(PTRACE_TRACEME, 0, (nil), (nil), 0)=0 called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 1196
Process 8832 launching
operation ptrace(PTRACE_PEEKDATA, 8832, 0x8048340, (nil), 0)=895EED31 called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 245
operation ptrace(PTRACE_POKEDATA, 8832, 0x8048340, 0x895eedcc, 0)=0 called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 319
operation ptrace(PTRACE_PEEKDATA, 8832, 0x8048340, (nil), 0)=895EEDCC called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 245
operation ptrace(PTRACE_POKEUSER, 8832, 0x2a8, 0xffffffff, 0)=FFFFFFFF called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 543
operation ptrace() failed; errno=5 (<unknown>)
lldb: /home/mg11/src/heracles2/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)

The source of the failure is now:

bool
RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t hw_index)
{
     bool is_hit = false;

     if (m_watchpoints_initialized == false)
     {
         // Reset the debug status and debug control registers
         RegisterValue zero_bits = RegisterValue(uint64_t(0));
         if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
--> assert(false && "Could not initialize watchpoint registers");

I'll re-sync and build, just to rule out my wimpy build environment, then start digging again...

Matt

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.

Initial investigations suggest that the offset of dr6 is being calculated incorrectly. The trace says 0x2A8, it should be 0x114.

(lldb) log enable linux ptrace
(lldb) run
operation ptrace(PTRACE_SETOPTIONS, 3665, (nil), 0x58, 0)=0 called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 1456
Process 3665 launching
operation ptrace(PTRACE_TRACEME, 0, (nil), (nil), 0)=0 called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 1196
operation ptrace(PTRACE_PEEKDATA, 3665, 0x8048340, (nil), 0)=895EED31 called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 245
operation ptrace(PTRACE_POKEDATA, 3665, 0x8048340, 0x895eedcc, 0)=0 called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 319
operation ptrace(PTRACE_PEEKDATA, 3665, 0x8048340, (nil), 0)=895EEDCC called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 245
MATTG IWH begin
WriteRegisterValue dr6 tid=3665 offset=2A8 val=FFFFFFFF
operation ptrace(PTRACE_POKEUSER, 3665, 0x2a8, 0xffffffff, 0)=FFFFFFFF called from file /home/mg11/src/heracles2/llvm/tools/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp line 543

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.

Hey Matthew,

Initial investigations suggest that the offset of dr6 is being calculated incorrectly. The trace says 0x2A8, it should be 0x114.

That sounds like you are once again seeing an x86_64 register infos section (using the x86_64 fpu register set) vs. the i386 set IIRC.

Your host is a 32-bit x86 architecture, right? (The one where you are running lldb?)

If you do a svn status or git status, can you double check that you don’t have any local changes? I’ll try on a 32-bit host with a clean repo to make sure I didn’t have any cruft on my end confusing the results.

Hey Matthew,

I just did a double check on my Ubuntu 13.10 x86 VM. Here were the results I got, which seem to be different than yours (I’ve got an x86 32-bit exe debugging fine with an x86 32-bit lldb):

tfiala@ub-x86-13:~/lldb/work/build$ uname -a
Linux ub-x86-13.10-01 3.11.0-17-generic #31-Ubuntu SMP Mon Feb 3 21:53:31 UTC 2014 i686 i686 i686 GNU/Linux
tfiala@ub-x86-13:~/lldb/work/build$ pushd …/llvm/tools/lldb
~/lldb/work/llvm/tools/lldb ~/lldb/work/build
tfiala@ub-x86-13:~/lldb/work/llvm/tools/lldb$ git log | head
commit aa7f071df1e47c4d63b4cab81c5b3a375e4b4a50
Author: Ed Maste <emaste@freebsd.org>

Fix types to eliminate compiler warnings in FreeBSD host class

git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@202498 91177308-0d34-0410-b5e6-96231b3b80d8

commit 3ca8916b078d298cc42ed61ffa2739c67daf7987
tfiala@ub-x86-13:~/lldb/work/llvm/tools/lldb$ # svn trunk@202498
tfiala@ub-x86-13:~/lldb/work/llvm/tools/lldb$ popd
~/lldb/work/build
tfiala@ub-x86-13:~/lldb/work/build$ file ~/play/size_data/main
/home/tfiala/play/size_data/main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x1749b467dda063db39d8bf61a26aec8e2f7a062e, not stripped
tfiala@ub-x86-13:~/lldb/work/build$ lldb -v
lldb: command not found
tfiala@ub-x86-13:~/lldb/work/build$ bin/lldb -v
lldb version 3.5 (http://llvm.org/git/lldb.git revision aa7f071df1e47c4d63b4cab81c5b3a375e4b4a50)
tfiala@ub-x86-13:~/lldb/work/build$ bin/lldb ~/play/size_data/main
Current executable set to ‘/home/tfiala/play/size_data/main’ (i386).
(lldb) b main.cpp:5
Breakpoint 1: where = main`main + 9 at main.cpp:5, address = 0x08048426
(lldb) run
Process 24270 launching
Process 24270 stopped

  • thread #1: tid = 24270, 0xb775f190, name = ‘main’, stop reason = trace
    frame #0: 0xb775f190
    → 0xb775f190: movl %esp, %eax
    0xb775f192: calll 0xb7762b70
    0xb775f197: movl %eax, %edi
    0xb775f199: calll 0xb775f180
    (lldb) Process 24270 launched: ‘/home/tfiala/play/size_data/main’ (i386)
    Process 24270 stopped
  • thread #1: tid = 24270, 0x08048426 mainmain + 9 at main.cpp:5, name = 'main', stop reason = breakpoint 1.1 frame #0: 0x08048426 mainmain + 9 at main.cpp:5
    2
    3 int main()
    4 {
    → 5 printf(“sizeof(long int): %u\n”, sizeof(long int));
    6 return 0;
    7 }
    (lldb) step
    Process 24270 stopped
  • thread #1: tid = 24270, 0xb75e27df libc.so.6__printf(format=0x080484e0) + 15 at printf.c:33, name = 'main', stop reason = step in frame #0: 0xb75e27df libc.so.6__printf(format=0x080484e0) + 15 at printf.c:33
    (lldb) bt
  • thread #1: tid = 24270, 0xb75e27df libc.so.6`__printf(format=0x080484e0) + 15 at printf.c:33, name = ‘main’, stop reason = step in
  • frame #0: 0xb75e27df libc.so.6__printf(format=0x080484e0) + 15 at printf.c:33 frame #1: 0x0804843a mainmain + 29 at main.cpp:5
    (lldb) exit
    Quitting LLDB will kill one or more processes. Do you really want to proceed: [Y/n] y
    tfiala@ub-x86-13:~/lldb/work/build$

I’m building with gcc 4.8.1 (stock on that machine), with packages:
swig
libedit-dev
python-dev
ncurses-dev

I happen to be using cmake/ninja to build this. If you’re using configure/make, I can try that too to make sure there isn’t any difference.

Just to add another data point here I pulled the latest and built on a 32-bit Ubuntu 12.04 machine using gcc 4.8.1 and configure/make (not cmake) I get the same error as Matthew.

andrew@linodebox:~/src/llvm/Release+Asserts/bin$ uname -a
Linux linodebox 3.12.6-x86-linode55 #2 SMP Tue Jan 14 08:41:36 EST 2014 i686 i686 i386 GNU/Linux
andrew@linodebox:~/src/llvm/Release+Asserts/bin$ ./lldb --version
lldb version 3.5 (http://llvm.org/git/lldb revision 18f105d6a0ec19261891cae0a70e1d12b0dd77db clang revision 30577e6c4f5ba66b8dc832ed9955b1a7475f788a llvm revision abad3545bdf7d89ea9b8c8e0ba30edc45c0118bb)
andrew@linodebox:~/src/llvm/Release+Asserts/bin$ cd …/…/tools/lldb/
andrew@linodebox:~/src/llvm/tools/lldb$ git log | head
commit 18f105d6a0ec19261891cae0a70e1d12b0dd77db
Author: Jim Ingham <jingham@apple.com>

Make sure the exe_ctx passed to ClangUserExpression::Execute has a valid thread.

rdar://problem/15949113

git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@202561 91177308-0d34-0410-b5e6-96231b3b80d8
andrew@linodebox:~/src/llvm/tools/lldb$ cd -
/home/andrew/src/llvm/Release+Asserts/bin
andrew@linodebox:~/src/llvm/Release+Asserts/bin$ file /usr/bin/python2.7
/usr/bin/python2.7: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xf96ecbe97bf2a78f1d3de7be85b849dfdcbb6083, stripped
andrew@linodebox:~/src/llvm/Release+Asserts/bin$ file lldb
lldb: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x670a204eb95a63dc2d59f7e16436de19be894446, not stripped
andrew@linodebox:~/src/llvm/Release+Asserts/bin$ ./lldb /usr/bin/python
Current executable set to ‘/usr/bin/python’ (i386).
(lldb) r
Process 12316 launching
lldb: RegisterContextPOSIXProcessMonitor_x86.cpp:511: virtual bool RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t): Assertion `false && “Could not initialize watchpoint registers”’ failed.
Aborted

Hope that helps,
Andrew

OK, I’ll try both configure build on 13.10 and 12.04, It could be an artifact of the build, or Ubuntu version, both of which differ here.

Todd Fiala wrote:

That sounds like you are once again seeing an x86_64 register infos section (using the x86_64 fpu register set) vs. the i386 set IIRC.

Your host is a 32-bit x86 architecture, right? (The one where you are running lldb?)

If you do a svn status or git status, can you double check that you don't have any local changes? I'll try on a 32-bit host with a clean repo to make sure I didn't have any cruft on my end confusing the results.

Hi Todd,

My RegisterContextLinux_i386.cpp is up to date. I think the offset calcuation was broken by r202428:

$ svn diff --old=RegisterContextLinux_i386.cpp@r202427 --new=RegisterContextLinux_i386.cpp@r202428
Index: RegisterContextLinux_i386.cpp

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.

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.

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@ubuntu:~$ mkdir play
tfiala@ubuntu:~$ cd play
tfiala@ubuntu:~/play$ mkdir c++
tfiala@ubuntu:~/play$ cd c++
tfiala@ubuntu:~/play/c++$ ls
tfiala@ubuntu:~/play/c++$ mkdir sizeof
tfiala@ubuntu:~/play/c++$ cd sizeof
tfiala@ubuntu:~/play/c++/sizeof$ vim sizeof.cpp

fiala@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@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@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@ubuntu:~/play/c++/sizeof$ g++ -O0 -g -Wall -o sizeof sizeof.cpp
tfiala@ubuntu:~/play/c++/sizeof$ ./sizeof
arg 0: ./sizeof
sizeof(short int): 2
sizeof(int): 4
sizeof(long): 4

tfiala@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 sizeofmain(argc=1, argv=0xbf8babf4) + 75 at sizeof.cpp:10, name = 'sizeof', stop reason = breakpoint 1.1 frame #0: 0x080484cb sizeofmain(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 sizeofmain(argc=1, argv=0xbf8babf4) + 95 at sizeof.cpp:11, name = 'sizeof', stop reason = step over frame #0: 0x080484df sizeofmain(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 sizeofmain(argc=1, argv=0xbf8babf4) + 115 at sizeof.cpp:12, name = 'sizeof', stop reason = step over frame #0: 0x080484f3 sizeofmain(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 sizeofmain(argc=1, argv=0xbf8babf4) + 135 at sizeof.cpp:14, name = 'sizeof', stop reason = step over frame #0: 0x08048507 sizeofmain(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@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@ubuntu:~/play/c++/sizeof$ pushd ~/lldb/git/llvm/tools/lldb/
~/lldb/git/llvm/tools/lldb ~/play/c++/sizeof
tfiala@ubuntu:~/lldb/git/llvm/tools/lldb$ git log | head
commit f8af40b976db2738b132caf21aff5be785d84211
Author: Deepak Panickal <deepak@codeplay.com>

Check if the terminal is interactive and set the flags accordingly

git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@202726 91177308-0d34-0410-b5e6-96231b3b80d8

commit 92309dd86ab11faf8daa72f3f47c4d0ea5fb51e0
Author: Deepak Panickal <deepak@codeplay.com>
tfiala@ubuntu:~/lldb/git/llvm/tools/lldb$

tfiala@ubuntu:~/lldb/git/llvm/tools/lldb$ git status

On branch master

nothing to commit (working directory clean)

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.

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@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@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 = sizeofmain + 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@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.

So I tried this patch:

tfiala@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]))

Todd Fiala wrote:

So I tried this patch:

tfiala@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.

Yes. That's a different (at least that's how I see it) assertion. It occurs because:

bool
RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t hw_index)
{
<snip>
         RegisterValue zero_bits = RegisterValue(uint64_t(0));
         if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))

doesn't write 0. It writes 0xffffffff. Which results in all breakpoint indexes being set but no watchpoints in lldb structures, hence the assert.

That's due to a combination of:

void
WriteRegOperation::Execute(ProcessMonitor *monitor)
{
<snip>
#if __WORDSIZE == 32
     buf = (void*) m_value.GetAsUInt32();
#else
     buf = (void*) m_value.GetAsUInt64();
#endif

and

uint32_t
RegisterValue::GetAsUInt32 (uint32_t fail_value, bool *success_ptr) const
{
<snip>
     switch (m_type)
     {
         default: break;
         case eTypeUInt8: return m_data.uint8;
         case eTypeUInt16: return m_data.uint16;
         case eTypeUInt32: return m_data.uint32;
         case eTypeFloat:
             if (sizeof(float) == sizeof(uint32_t))
                 return m_data.uint32;
             break;
<snip>
     return fail_value;
}

but I have a sweet fix for this, which doesn't compromise the design of RegisterValue. With this fix and the correct i386 register map, I think we're looking good for 32-bit linux.

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

No sweat :wink:

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

Yeah, I appreciate that. You can't rely on the presence of the "right" user.h. To calculate the offsets you'd need to either i) copy the structures or ii) hard-code the offsets. My contention isn't over the *copying*, it's over the usage of structures, when they're not also being used as structures. I think if the actual offsets e.g.

...
const uint32_t kDebugRegister6_Offset = 0x114;
const uint32_t kDebugRegister7_Offset = 0x118;
...

are crafted, then we have more robust code, since breakage would require people deliberately changing a number, instead of a more subtle structure edit. Anyway, that's just my opinion.

thanks
Matt

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.

Thanks Matt.

Right now I’m going to try what I think are the last two patches you had put up since we last chatted (my last night).

tfiala@tfiala2:/mnt/ssd/work/svn/lgs/llvm/tools/lldb$ svn commit
Sending source/Plugins/Process/Linux/ProcessMonitor.cpp

Sending source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp
Transmitting file data …
Committed revision 202887