[Dexter] Update lldb-based dexter-tests to use script-mode (#204367)

This patch replaces uses of heuristic-mode Dexter in the dexter-tests
suite with uses of the script-mode, for tests that use DAP (via
lldb-dap). The updates are largely straightforward but occasionally
non-trivial, and in some cases some slight modifications have been made
to keep the "spirit" of the test intact.
This commit is contained in:
Stephen Tozer 2026-07-02 19:27:35 +01:00 committed by GitHub
parent 5587443d5f
commit db5740f1a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 693 additions and 412 deletions

View file

@ -2,8 +2,8 @@
// UNSUPPORTED: system-windows
//
// RUN: %clang++ -std=gnu++11 -O0 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
// Radar 8945514
class SVal {
@ -16,7 +16,7 @@ public:
void bar(SVal &v) {}
class A {
public:
void foo(SVal v) { bar(v); } // DexLabel('foo')
void foo(SVal v) { bar(v); } // !dex_label foo
};
int main() {
@ -28,17 +28,14 @@ int main() {
return 0;
}
/*
DexExpectProgramState({
'frames': [
{
'location': { 'lineno': ref('foo') },
'watches': {
'v.Data == 0': 'true',
'v.Kind': '2142'
}
}
]
})
*/
// CHECK-DAG: seen_values: 2
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label foo}:
!value v:
Kind: 2142
!value "v.Data == 0": "true"
...
*/

View file

@ -8,9 +8,10 @@
// lldb-8, even outside of dexter, will sometimes trigger an asan fault in
// the debugged process and generally freak out.
// RUN: %clang++ -std=gnu++11 -O1 -glldb -fsanitize=address -arch x86_64 %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %clang++ -std=gnu++11 -O1 -glldb -fsanitize=address -arch x86_64 %s \
// RUN: -o %t
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
#include <deque>
struct A {
@ -32,16 +33,28 @@ int main() {
deq_t deq;
deq.push_back(1234);
deq.push_back(56789);
escape(deq); // DexLabel('first')
escape(deq); // !dex_label first
while (!deq.empty()) {
auto record = deq.front();
deq.pop_front();
escape(deq); // DexLabel('second')
escape(deq); // !dex_label second
}
}
// DexExpectWatchValue('deq[0].a', '1234', on_line=ref('first'))
// DexExpectWatchValue('deq[1].a', '56789', on_line=ref('first'))
// DexExpectWatchValue('deq[0].a', '56789', '0', on_line=ref('second'))
// CHECK-DAG: seen_values: 3
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label first}:
!value deq:
"[0]":
a: 1234
"[1]":
a: 56789
!where {lines: !label second}:
!value deq:
"[0]":
a: 56789
...
*/

View file

@ -5,15 +5,15 @@
//
// RUN: %clang -std=gnu11 --driver-mode=gcc -O0 -glldb -fblocks -arch x86_64 \
// RUN: -fsanitize=address %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
struct S {
int a[8];
};
int f(struct S s, unsigned i) {
return s.a[i]; // DexLabel('asan')
return s.a[i]; // !dex_label asan
}
int main(int argc, const char **argv) {
@ -23,7 +23,16 @@ int main(int argc, const char **argv) {
return 0;
}
// DexExpectWatchValue('s.a[0]', '0', on_line=ref('asan'))
// DexExpectWatchValue('s.a[1]', '1', on_line=ref('asan'))
// DexExpectWatchValue('s.a[7]', '7', on_line=ref('asan'))
// CHECK-DAG: seen_values: 3
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label asan}:
!value s:
a:
"[0]": 0
"[1]": 1
"[7]": 7
...
*/

View file

@ -2,12 +2,12 @@
// UNSUPPORTED: system-windows
//
// RUN: %clang++ -std=gnu++11 -O0 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
class A {
public:
A() : zero(0), data(42) { // DexLabel('ctor_start')
A() : zero(0), data(42) { // !dex_label ctor_start
}
private:
int zero;
@ -19,19 +19,13 @@ int main() {
return 0;
}
// CHECK-DAG: total_watched_steps: 1
// CHECK-DAG: irretrievable_steps: 0
/*
DexExpectProgramState({
'frames': [
{
'location': {
'lineno': ref('ctor_start')
},
'watches': {
'*this': {'is_irretrievable': False}
}
}
]
})
---
!where {lines: !label ctor_start}:
!value this:
"*": "{}"
...
*/

View file

@ -3,8 +3,8 @@
//
// This test case checks debug info during register moves for an argument.
// RUN: %clang -std=gnu11 -m64 -mllvm -fast-isel=false -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
//
// Radar 8412415
@ -22,7 +22,7 @@ int bar(int, int);
int foobar(struct _mtx *mutex) {
int r = 1;
int l = 0; // DexLabel('l_assign')
int l = 0; // !dex_label l_assign
int j = 0;
do {
if (mutex->waiters) {
@ -44,17 +44,13 @@ int main() {
return foobar(&m);
}
// CHECK-DAG: total_watched_steps: 1
// CHECK-DAG: irretrievable_steps: 0
/*
DexExpectProgramState({
'frames': [
{
'location': { 'lineno': ref('l_assign') },
'watches': {
'*mutex': { 'is_irretrievable': False }
}
}
]
})
---
!where {lines: !label l_assign}:
!value mutex:
"*": "{}"
...
*/

View file

@ -5,8 +5,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang++ -std=gnu++11 -O0 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -v -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -v -- %s | FileCheck %s
const int d = 100;
@ -14,15 +14,23 @@ extern int foo();
int main() {
const int d = 4;
const float e = 4; // DexLabel("main")
const float e = 4; // !dex_label main
const char *f = "Woopy";
return d + foo();
}
int foo() {
return d; // DexLabel("foo")
return d; // !dex_label foo
}
// DexExpectWatchValue('d', '4', on_line=ref('main'))
// DexExpectWatchValue('d', '100', on_line=ref('foo'))
// CHECK-DAG: seen_values: 2
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label main}:
!value d: 4
!where {lines: !label foo}:
!value d: 100
...
*/

View file

@ -4,7 +4,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O3 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter --use-script -w --use-script %dexter_lldb_args --binary %t \
// RUN: -- %s | FileCheck %s
//// Adapted from https://bugs.llvm.org/show_bug.cgi?id=34136#c1
//// LowerDbgDeclare has since been updated to look through bitcasts. We still
@ -64,14 +65,24 @@ void alias(char* c) {
int main() {
int x = getint(5);
int y = getint(5); // DexLabel('s1')
int z = getint(5); // DexLabel('s2')
alias((char*)&x); // DexLabel('s3')
int y = getint(5); // !dex_label s1
int z = getint(5); // !dex_label s2
alias((char*)&x); // !dex_label s3
alias((char*)&y);
alias((char*)&z);
return 0; // DexLabel('s4')
return 0; // !dex_label s4
}
// DexExpectWatchValue('x', '5', from_line=ref('s1'), to_line=ref('s4'))
// DexExpectWatchValue('y', '5', from_line=ref('s2'), to_line=ref('s4'))
// DexExpectWatchValue('z', '5', from_line=ref('s3'), to_line=ref('s4'))
// CHECK-DAG: seen_values: 3
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !range [!label s1, !label s4]}:
!value x: 5
!where {lines: !range [!label s2, !label s4]}:
!value y: 5
!where {lines: !range [!label s3, !label s4]}:
!value z: 5
...
*/

View file

@ -4,7 +4,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O3 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
//// Adapted from https://bugs.llvm.org/show_bug.cgi?id=34136#c4
@ -23,7 +24,7 @@ void thing(int x) {
__attribute__((__noinline__))
int fun(int param) {
esc(&param); //// alloca is live until here DexLabel('s1')
esc(&param); //// alloca is live until here !dex_label s1
if (param == 0) { //// end of alloca live range
//// param is now a constant, but without lowering to dbg.value we can't
//// capture that and would still point to the stack slot that may even have
@ -41,12 +42,19 @@ int fun(int param) {
//// CMP32mi8 %param.addr, 1, $noreg, 0, $noreg, 0, implicit-def $eflags, debug-location !44
thing(param);
}
return 0; // DexLabel('s2')
return 0; // !dex_label s2
}
int main() {
return fun(5);
}
// DexExpectWatchValue('param', '5', from_line=ref('s1'), to_line=ref('s2'))
// CHECK-DAG: seen_values: 1
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !range [!label s1, !label s2]}:
!value param: 5
...
*/

View file

@ -1,7 +1,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O2 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
//// Check that we give good locations to a variable ('local') which is escaped
//// down some control paths and not others. This example is handled well currently.
@ -15,12 +16,12 @@ void leak(int *ptr) {
__attribute__((__noinline__))
int fun(int cond) {
int local = 0; // DexLabel('s1')
int local = 0; // !dex_label s1
if (cond)
leak(&local);
else
local = 1;
return local; // DexLabel('s2')
return local; // !dex_label s2
}
int main() {
@ -29,6 +30,15 @@ int main() {
return a + b;
}
//// fun(1) fun(0)
// DexExpectWatchValue('local', '0', '0', on_line=ref('s1'))
// DexExpectWatchValue('local', '2', '1', on_line=ref('s2'))
// CHECK-DAG: seen_values: 3
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {function: "fun"}:
!and {lines: !label s1}:
!value local: 0
!and {lines: !label s2}:
!value local: [2, 1]
...
*/

View file

@ -4,7 +4,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O3 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
//// Check that 'param' in 'fun' can be read throughout, and that 'pa' and 'pb'
//// can be dereferenced in the debugger even if we can't provide the pointer
@ -18,28 +19,40 @@ int globb;
__attribute__((__noinline__))
static void use_promote(const int* pa) {
//// Promoted args would be a good candidate for an DW_OP_implicit_pointer.
globa = *pa; // DexLabel('s2')
globa = *pa; // !dex_label s2
}
__attribute__((__always_inline__))
static void use_inline(const int* pb) {
//// Inlined pointer to callee local would be a good candidate for an
//// DW_OP_implicit_pointer.
globb = *pb; // DexLabel('s3')
globb = *pb; // !dex_label s3
}
__attribute__((__noinline__))
int fun(int param) {
volatile int step = 0; // DexLabel('s1')
volatile int step = 0; // !dex_label s1
use_promote(&param);
use_inline(&param);
return step; // DexLabel('s4')
return step; // !dex_label s4
}
int main() {
return fun(5);
}
// DexExpectWatchValue('param', 5, from_line=ref('s1'), to_line=ref('s4'))
// DexExpectWatchValue('*pa', 5, on_line=ref('s2'))
// DexExpectWatchValue('*pb', 5, on_line=ref('s3'))
// CHECK-DAG: seen_values: 3
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !range [!label s1, !label s4]}:
!value param: 5
!where {lines: !label s2}:
!value pa:
"*": 5
!where {lines: !label s3}:
!value pa:
"*": 5
...
*/

View file

@ -4,7 +4,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O3 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
// 1. param is escaped by inlineme(&param) so it is not promoted by
// SROA/mem2reg.
@ -34,7 +35,7 @@ __attribute__((noinline))
int fun(int param) {
if (param)
param = inlineme(&param);
fluff(); // DexLabel('s0')
fluff(); // !dex_label s0
return param;
}
@ -42,4 +43,12 @@ int main() {
return fun(5);
}
// DexExpectWatchValue('param', 10, on_line=ref('s0'))
// CHECK-DAG: seen_values: 1
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label s0}:
!value param: 10
...
*/

View file

@ -4,7 +4,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O2 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
//
//// Check that once-escaped variable 'param' can still be read after we
//// perform inlining + mem2reg, and that we see the DSE'd value 255.
@ -15,38 +16,35 @@ __attribute__((__always_inline__))
static void use(int* p) {
g = *p;
*p = 255;
volatile int step = 0; // DexLabel('use1')
volatile int step = 0; // !dex_label use1
}
__attribute__((__noinline__))
void fun(int param) {
//// Make sure first step is in 'fun'.
volatile int step = 0; // DexLabel('fun1')
volatile int step = 0; // !dex_label fun1
use(&param);
return; // DexLabel('fun2')
return; // !dex_label fun2
}
int main() {
fun(5);
}
// CHECK-DAG: seen_values: 3
// CHECK-DAG: correct_step_coverage: 100.0%
/*
# Expect param == 5 before stepping through inlined 'use'.
DexExpectWatchValue('param', '5', on_line=ref('fun1'))
# Expect param == 255 after assignment in inlined frame 'use'.
DexExpectProgramState({
'frames': [
{ 'function': 'use',
'location': { 'lineno': ref('use1') },
},
{ 'function': 'fun',
'location': { 'lineno': 20 },
'watches': { 'param': '255' }
},
]
})
# Expect param == 255 after inlined call to 'use'.
DexExpectWatchValue('param', '255', on_line=ref('fun2'))
---
!where {function: fun}:
# Expect param == 5 before stepping through inlined 'use'.
!and {lines: !label fun1}:
!value param: 5
# Expect param == 255 after assignment in inlined frame 'use'.
!and {lines: !label fun2}:
!value param: 255
!where {file: "inlining-dse.c", lines: !label use1}:
!and {at_frame_idx: 1}:
!value param: 255
...
*/

View file

@ -1,7 +1,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O2 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
//
//// Check that the once-escaped variable 'param' can still be read after
//// we perform inlining + mem2reg. See D89810 and D85555.
@ -14,13 +15,21 @@ static void use(int* p) {
__attribute__((__noinline__))
void fun(int param) {
volatile int step1 = 0; // DexLabel('s1')
volatile int step1 = 0; // !dex_label s1
use(&param);
volatile int step2 = 0; // DexLabel('s2')
volatile int step2 = 0; // !dex_label s2
}
int main() {
fun(5);
}
// DexExpectWatchValue('param', '5', from_line=ref('s1'), to_line=ref('s2'))
// CHECK-DAG: seen_values: 1
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !range [!label s1, !label s2]}:
!value param: 5
...
*/

View file

@ -4,7 +4,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O3 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
//// Check that escaped local 'param' in function 'fun' has sensible debug info
//// after the escaping function 'use' gets arg promotion (int* -> int). Currently
@ -17,7 +18,7 @@ __attribute__((__noinline__))
static void use(const int* p) {
//// Promoted args would be a good candidate for an DW_OP_implicit_pointer.
//// This desirable behaviour is checked for in the test implicit-ptr.c.
g = *p;
g = *p; // !dex_label s1
}
__attribute__((__noinline__))
@ -27,7 +28,7 @@ void do_thing(int x) {
__attribute__((__noinline__))
int fun(int param) {
do_thing(0); // DexLabel('s2')
do_thing(0); // !dex_label s2
for (int i = 0; i < param; ++i) {
use(&param);
}
@ -45,12 +46,22 @@ int fun(int param) {
//// [0x0000000000400495, 0x00000000004004a2): DW_OP_reg3 RBX)
//// DW_AT_name ("param")
return g; // DexLabel('s3')
return g; // !dex_label s3
}
int main() {
return fun(5);
}
// DexExpectWatchValue('*p', 5, 5, 5, 5, 5, on_line=ref('s1'))
// DexExpectWatchValue('param', 5, from_line=ref('s2'), to_line=ref('s3'))
// CHECK-DAG: seen_values: 2
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label s1}:
!value p:
"*": 5
!where {lines: !range [!label s2, !label s3]}:
!value param: 5
...
*/

View file

@ -4,7 +4,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O3 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
// 1. parama is escaped by esc(&parama) so it is not promoted by
// SROA/mem2reg.
@ -31,7 +32,7 @@ __attribute__((noinline))
int fun(int parama, int paramb) {
if (parama)
parama = paramb;
fluff(); // DexLabel('s0')
fluff(); // !dex_label s0
esc(&parama);
return 0;
}
@ -40,4 +41,12 @@ int main() {
return fun(5, 20);
}
// DexExpectWatchValue('parama', 20, on_line=ref('s0'))
// CHECK-DAG: seen_values: 1
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label s0}:
!value param: 20
...
*/

View file

@ -5,7 +5,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O2 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
//
//// Check that a pointer to a variable living on the stack dereferences to the
//// variable value.
@ -20,16 +21,27 @@ void esc(int* p) {
int main() {
int local = 0xA;
int *plocal = &local;
esc(plocal); // DexLabel('s1')
esc(plocal); // !dex_label s1
local = 0xB; //// DSE
return 0; // DexLabel('s2')
return 0; // !dex_label s2
}
// CHECK-DAG: seen_values: 5
// CHECK-DAG: correct_step_coverage: 100.0%
// DexExpectWatchValue('local', 0xA, on_line=ref('s1'))
// DexExpectWatchValue('local', 0xB, on_line=ref('s2'))
// DexExpectWatchValue('*plocal', 0xA, on_line=ref('s1'))
// DexExpectWatchValue('*plocal', 0xB, on_line=ref('s2'))
//// Ideally we should be able to observe the dead store to local (0xB) through
//// plocal here.
// DexExpectWatchValue('(local == *plocal)', 'true', from_line=ref('s1'), to_line=ref('s2'))
/*
---
!where {lines: !label s1}:
!value local: 0xA
!value plocal:
"*": 0xA
!where {lines: !label s2}:
!value local: 0xB
!value plocal:
"*": 0xB
# Ideally we should be able to observe the dead store to local (0xB) through
# plocal here.
!where {lines: !range [!label s1, !label s2]}:
!value "(local == *plocal)": true
...
*/

View file

@ -5,7 +5,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O2 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
//
//// Check debug-info for the escaped struct variable num is reasonable.
@ -22,14 +23,25 @@ void esc(struct Nums* nums) {
__attribute__((__noinline__))
int main() {
struct Nums nums = { .c=1 }; //// Dead store.
printf("s1 nums.c: %d\n", nums.c); // DexLabel('s1')
printf("s1 nums.c: %d\n", nums.c); // !dex_label s1
nums.c = 2; //// Killing store.
printf("s2 nums.c: %d\n", nums.c); // DexLabel('s2')
printf("s2 nums.c: %d\n", nums.c); // !dex_label s2
esc(&nums); //// Force nums to live on the stack.
return 0; // DexLabel('s3')
return 0; // !dex_label s3
}
// DexExpectWatchValue('nums.c', '1', on_line=ref('s1'))
// DexExpectWatchValue('nums.c', '2', from_line=ref('s2'), to_line=ref('s3'))
// CHECK-DAG: seen_values: 2
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label s1}:
!value nums:
c: 1
!where {lines: !range [!label s2, !label s3]}:
!value nums:
c: 2
...
*/

View file

@ -6,7 +6,8 @@
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %clang -std=gnu11 -O3 -glldb %s -o %t
// RUN: %dexter --fail-lt 0.1 -w %dexter_lldb_args --binary %t -- %s
// RUN: %dexter -w --use-script %dexter_lldb_args --binary %t -- %s \
// RUN: | FileCheck %s
// See NOTE at end for more info about the RUN command.
// 1. SROA/mem2reg fully promotes parama.
@ -30,7 +31,7 @@ __attribute__((noinline))
int fun(int parama, int paramb) {
if (parama)
parama = paramb;
fluff(); // DexLabel('s0')
fluff(); // !dex_label s0
return paramb;
}
@ -38,9 +39,19 @@ int main() {
return fun(5, 20);
}
// DexExpectWatchValue('parama', 20, on_line=ref('s0'))
//
// NOTE: the dexter command uses --fail-lt 0.1 (instead of the standard 1.0)
// because seeing 'optimized out' would still be a win; it's the best we can do
// without using conditional DWARF operators in the location expression. Seeing
// 'optimized out' should result in a score higher than 0.1.
// NOTE: we check for optimized_out_steps instead of correct_steps, because
// parama being 'optimized out' instead of missing is the best we can do without
// using conditional DWARF operators in the location expression. Therefore, this
// test will still pass if we see "optimized out" instead of "missing".
// If we ever manage to recover this variable information, then we can update
// this test to expect correctness.
// CHECK: optimized_out_steps: 1
// CHECK: missing_var_steps: 0
/*
---
!where {lines: !label s0}:
!value parama: 20
...
*/

View file

@ -6,8 +6,8 @@
// UNSUPPORTED: system-windows
// RUN: %clang++ -g -O0 %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -v -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -v -- %s | FileCheck %s
#include <stdio.h>
@ -16,9 +16,16 @@ const int ape = 32;
}
int main() {
printf("hello %d\n", monkey::ape); // DexLabel('main')
printf("hello %d\n", monkey::ape); // !dex_label main
return 0;
}
// DexExpectWatchValue('monkey::ape', 32, on_line=ref('main'))
// CHECK-DAG: seen_values: 1
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label main}:
!value "monkey::ape": 32
...
*/

View file

@ -8,12 +8,12 @@
// compiler-rt. Only run this test on non-asanified configurations.
//
// RUN: %clang++ -std=gnu++11 -O0 -glldb -fno-exceptions %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
//
// RUN: %clang++ -std=gnu++11 -O1 -glldb -fno-exceptions %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
//
// PR34513
volatile int sideeffect = 0;
@ -28,7 +28,7 @@ struct string {
string __attribute__((noinline)) get_string() {
string unused;
string output = 3;
stop(); // DexLabel('string-nrvo')
stop(); // !dex_label string-nrvo
return output;
}
void some_function(int) {}
@ -43,7 +43,7 @@ string2 __attribute__((noinline)) get_string2() {
some_function(output.i);
// Test that the debugger can get the value of output after another
// function is called.
stop(); // DexLabel('string2-nrvo')
stop(); // !dex_label string2-nrvo
return output;
}
int main() {
@ -51,6 +51,16 @@ int main() {
get_string2();
}
// DexExpectWatchValue('output.i', 3, on_line=ref('string-nrvo'))
// DexExpectWatchValue('output.i', 5, on_line=ref('string2-nrvo'))
// CHECK-DAG: seen_values: 2
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label string-nrvo}:
!value output:
i: 3
!where {lines: !label string2-nrvo}:
!value output:
i: 5
...
*/

View file

@ -1,9 +1,9 @@
// RUN: %clang++ -std=gnu++11 -O2 -ffast-math -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
// RUN: %clang++ -std=gnu++11 -O0 -ffast-math -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
// REQUIRES: lldb
// Currently getting intermittent failures on darwin.
@ -21,24 +21,19 @@
__attribute__((optnone))
float test_fdiv(float A) {
float result;
result = A / 10.f; // DexLabel('fdiv_assign')
return result; // DexLabel('fdiv_ret')
result = A / 10.f; // !dex_label fdiv_assign
return result; // !dex_label fdiv_ret
}
// DexExpectWatchValue('A', 4, on_line=ref('fdiv_assign'))
// DexExpectWatchValue('result', '0.400000006', on_line=ref('fdiv_ret'))
//// (A * B) - (A * C) ==> A * (B - C)
__attribute__((optnone))
float test_distributivity(float A, float B, float C) {
float result;
float op1 = A * B;
float op2 = A * C; // DexLabel('distributivity_op2')
result = op1 - op2; // DexLabel('distributivity_result')
return result; // DexLabel('distributivity_ret')
float op2 = A * C; // !dex_label distributivity_op2
result = op1 - op2; // !dex_label distributivity_result
return result; // !dex_label distributivity_ret
}
// DexExpectWatchValue('op1', '20', on_line=ref('distributivity_op2'))
// DexExpectWatchValue('op2', '24', on_line=ref('distributivity_result'))
// DexExpectWatchValue('result', '-4', on_line=ref('distributivity_ret'))
//// (A + B) + C == A + (B + C)
//// therefore, ((A + B) + C) + (A + (B + C)))
@ -51,14 +46,11 @@ float test_associativity(float A, float B, float C) {
float result;
float op1 = A + B;
float op2 = B + C;
op1 += C; // DexLabel('associativity_op1')
op1 += C; // !dex_label associativity_op1
op2 += A;
result = op1 + op2; // DexLabel('associativity_result')
return result; // DexLabel('associativity_ret')
result = op1 + op2; // !dex_label associativity_result
return result; // !dex_label associativity_ret
}
// DexExpectWatchValue('op1', '9', '15', from_line=ref('associativity_op1'), to_line=ref('associativity_result'))
// DexExpectWatchValue('op2', '11', '15', from_line=ref('associativity_op1'), to_line=ref('associativity_result'))
// DexExpectWatchValue('result', '30', on_line=ref('associativity_ret'))
//// With fastmath, the ordering of instructions doesn't matter
//// since we work under the assumption that there is no loss
@ -72,28 +64,21 @@ float test_associativity(float A, float B, float C) {
//// This function can be simplified to a return A + B.
__attribute__((optnone))
float test_simplify_fp_operations(float A, float B) {
float result = A + 10.0f; // DexLabel('fp_operations_result')
result += B; // DexLabel('fp_operations_add')
float result = A + 10.0f; // !dex_label fp_operations_result
result += B; // !dex_label fp_operations_add
result -= 10.0f;
return result; // DexLabel('fp_operations_ret')
return result; // !dex_label fp_operations_ret
}
// DexExpectWatchValue('A', '8.25', on_line=ref('fp_operations_result'))
// DexExpectWatchValue('B', '26.3999996', on_line=ref('fp_operations_result'))
// DexExpectWatchValue('result', '18.25', '44.6500015', '34.6500015', from_line=ref('fp_operations_add'), to_line=ref('fp_operations_ret'))
//// Again, this is a simple return A + B.
//// Clang is unable to spot the opportunity to fold the code sequence.
__attribute__((optnone))
float test_simplify_fp_operations_2(float A, float B, float C) {
float result = A + C; // DexLabel('fp_operations_2_result')
float result = A + C; // !dex_label fp_operations_2_result
result += B;
result -= C; // DexLabel('fp_operations_2_subtract')
return result; // DexLabel('fp_operations_2_ret')
result -= C; // !dex_label fp_operations_2_subtract
return result; // !dex_label fp_operations_2_ret
}
// DexExpectWatchValue('A', '9.11999988', on_line=ref('fp_operations_2_result'))
// DexExpectWatchValue('B', '61.050003', on_line=ref('fp_operations_2_result'))
// DexExpectWatchValue('C', '1002.11102', on_line=ref('fp_operations_2_result'))
// DexExpectWatchValue('result', '1072.28101', '70.1699829', from_line=ref('fp_operations_2_subtract'), to_line=ref('fp_operations_2_ret'))
int main() {
float result = test_fdiv(4.0f);
@ -103,3 +88,43 @@ int main() {
result += test_simplify_fp_operations_2(9.12, result, 1002.111);
return static_cast<int>(result);
}
// CHECK-DAG: seen_values: 20
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {function: test_fdiv}:
!and {lines: !label fdiv_assign}:
!value A: 4
!and {lines: !label fdiv_ret}:
!value result: "0.400000006"
!where {function: test_distributivity}:
!and {lines: !label distributivity_op2}:
!value op1: 20
!and {lines: !label distributivity_result}:
!value op2: 24
!and {lines: !label distributivity_ret}:
!value result: -4
!where {function: test_associativity}:
!and {lines: !range [!label associativity_op1, !label associativity_result]}:
!value op1: [9, 15]
!value op2: [11, 15]
!and {lines: !label associativity_ret}:
!value result: 30
!where {function: test_simplify_fp_operations}:
!and {lines: !label fp_operations_result}:
!value A: "8.25"
!value B: "26.3999996"
!and {lines: !range [!label fp_operations_add, !label fp_operations_ret]}:
!value result: ["18.25", "44.6500015", "34.6500015"]
!where {function: test_simplify_fp_operations_2}:
!and {lines: !label fp_operations_2_result}:
!value A: '9.11999988'
!value B: '61.050003'
!value C: '1002.11102'
? !and
lines: !range [!label fp_operations_2_subtract, !label fp_operations_2_ret]
: !value result: ["1072.28101", "70.1699829"]
...
*/

View file

@ -6,8 +6,8 @@
// UNSUPPORTED: system-darwin
// RUN: %clang++ -std=gnu++11 -O2 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
// A simple loop of assignments.
// With optimization level > 0 the compiler reorders basic blocks
@ -19,63 +19,37 @@
__attribute__((optnone)) void simple_memcpy_loop(int *dest, const int *src,
unsigned nelems) {
for (unsigned i = 0; i != nelems; ++i)
dest[i] = src[i]; // DexLabel('target_simple_memcpy_loop')
dest[i] = src[i]; // !dex_label simple_memcpy_loop
}
// DexLimitSteps('i', 0, 4, 8, on_line=ref('target_simple_memcpy_loop'))
// DexExpectWatchValue('nelems', '16', on_line=ref('target_simple_memcpy_loop'))
// DexExpectWatchValue('src[i]', '3', '7', '1', on_line=ref('target_simple_memcpy_loop'))
// A trivial loop that could be optimized into a builtin memcpy
// which is either expanded into a optimal sequence of mov
// instructions or directly into a call to memset@plt
__attribute__((optnone)) void trivial_memcpy_loop(int *dest, const int *src) {
for (unsigned i = 0; i != 16; ++i)
dest[i] = src[i]; // DexLabel('target_trivial_memcpy_loop')
dest[i] = src[i]; // !dex_label trivial_memcpy_loop
}
// DexLimitSteps('i', 3, 7, 9, 14, 15, on_line=ref('target_trivial_memcpy_loop'))
// DexExpectWatchValue('i', 3, 7, 9, 14, 15, on_line=ref('target_trivial_memcpy_loop'))
// DexExpectWatchValue('dest[i-1] == src[i-1]', 'true', on_line=ref('target_trivial_memcpy_loop'))
__attribute__((always_inline)) int foo(int a) { return a + 5; }
// A trivial loop of calls to a 'always_inline' function.
__attribute__((optnone)) void nonleaf_function_with_loop(int *dest,
const int *src) {
for (unsigned i = 0; i != 16; ++i)
dest[i] = foo(src[i]); // DexLabel('target_nonleaf_function_with_loop')
dest[i] = foo(src[i]); // !dex_label nonleaf_function_with_loop
}
// DexLimitSteps('i', 1, on_line=ref('target_nonleaf_function_with_loop'))
// DexExpectWatchValue('dest[0]', '8', on_line=ref('target_nonleaf_function_with_loop'))
// DexExpectWatchValue('dest[1]', '4', on_line=ref('target_nonleaf_function_with_loop'))
// DexExpectWatchValue('dest[2]', '5', on_line=ref('target_nonleaf_function_with_loop'))
// DexExpectWatchValue('src[0]', '8', on_line=ref('target_nonleaf_function_with_loop'))
// DexExpectWatchValue('src[1]', '4', on_line=ref('target_nonleaf_function_with_loop'))
// DexExpectWatchValue('src[2]', '5', on_line=ref('target_nonleaf_function_with_loop'))
// DexExpectWatchValue('src[1] == dest[1]', 'true', on_line=ref('target_nonleaf_function_with_loop'))
// DexExpectWatchValue('src[2] == dest[2]', 'true', on_line=ref('target_nonleaf_function_with_loop'))
// This entire function could be optimized into a
// simple movl %esi, %eax.
// That is because we can compute the loop trip count
// knowing that ind-var 'i' can never be negative.
__attribute__((optnone)) int counting_loop(unsigned values) {
unsigned i = 0;
while (values--) // DexLabel('target_counting_loop')
while (values--) // !dex_label counting_loop
i++;
return i;
}
// DexLimitSteps('i', 8, 16, on_line=ref('target_counting_loop'))
// DexExpectWatchValue('i', 8, 16, on_line=ref('target_counting_loop'))
// This loop could be rotated.
// while(cond){
// ..
@ -99,18 +73,12 @@ __attribute__((optnone)) int loop_rotate_test(int *src, unsigned count) {
int result = 0;
while (count) {
result += src[count - 1]; // DexLabel('target_loop_rotate_test')
result += src[count - 1]; // !dex_label loop_rotate_test
count--;
}
return result; // DexLabel('target_loop_rotate_test_ret')
return result; // !dex_label loop_rotate_test_ret
}
// DexLimitSteps('result', 13, on_line=ref('target_loop_rotate_test'))
// DexExpectWatchValue('src[count]', 13, on_line=ref('target_loop_rotate_test'))
// DexLimitSteps('result', 158, on_line=ref('target_loop_rotate_test_ret'))
// DexExpectWatchValue('result', 158, on_line=ref('target_loop_rotate_test_ret'))
typedef int *intptr __attribute__((aligned(16)));
// This loop can be vectorized if we enable
@ -120,30 +88,19 @@ __attribute__((optnone)) void loop_vectorize_test(intptr dest, intptr src) {
int tempArray[16];
while(count != 16) { // DexLabel('target_loop_vectorize_test')
while (count != 16) { // !dex_label loop_vectorize_test
tempArray[count] = src[count];
tempArray[count+1] = src[count+1]; // DexLabel('target_loop_vectorize_test_2')
tempArray[count+2] = src[count+2]; // DexLabel('target_loop_vectorize_test_3')
tempArray[count+3] = src[count+3]; // DexLabel('target_loop_vectorize_test_4')
dest[count] = tempArray[count]; // DexLabel('target_loop_vectorize_test_5')
dest[count+1] = tempArray[count+1]; // DexLabel('target_loop_vectorize_test_6')
dest[count+2] = tempArray[count+2]; // DexLabel('target_loop_vectorize_test_7')
dest[count+3] = tempArray[count+3]; // DexLabel('target_loop_vectorize_test_8')
count += 4; // DexLabel('target_loop_vectorize_test_9')
tempArray[count + 1] = src[count + 1]; // !dex_label loop_vectorize_test_2
tempArray[count + 2] = src[count + 2]; // !dex_label loop_vectorize_test_3
tempArray[count + 3] = src[count + 3]; // !dex_label loop_vectorize_test_4
dest[count] = tempArray[count]; // !dex_label loop_vectorize_test_5
dest[count + 1] = tempArray[count + 1]; // !dex_label loop_vectorize_test_6
dest[count + 2] = tempArray[count + 2]; // !dex_label loop_vectorize_test_7
dest[count + 3] = tempArray[count + 3]; // !dex_label loop_vectorize_test_8
count += 4; // !dex_label loop_vectorize_test_9
}
}
// DexLimitSteps('count', 4, 8, 12, 16, from_line=ref('target_loop_vectorize_test'), to_line=ref('target_loop_vectorize_test_9'))
// DexExpectWatchValue('tempArray[count] == src[count]', 'true', on_line=ref('target_loop_vectorize_test_2'))
// DexExpectWatchValue('tempArray[count+1] == src[count+1]', 'true', on_line=ref('target_loop_vectorize_test_3'))
// DexExpectWatchValue('tempArray[count+2] == src[count+2]', 'true', on_line=ref('target_loop_vectorize_test_4'))
// DexExpectWatchValue('tempArray[count+3] == src[count+3]', 'true', on_line=ref('target_loop_vectorize_test_5'))
// DexExpectWatchValue('dest[count] == tempArray[count]', 'true', on_line=ref('target_loop_vectorize_test_6'))
// DexExpectWatchValue('dest[count+1] == tempArray[count+1]', 'true', on_line=ref('target_loop_vectorize_test_7'))
// DexExpectWatchValue('dest[count+2] == tempArray[count+2]', 'true', on_line=ref('target_loop_vectorize_test_8'))
// DexExpectWatchValue('dest[count+3] == tempArray[count+3]', 'true', on_line=ref('target_loop_vectorize_test_9'))
int main() {
int A[] = {3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int B[] = {13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
@ -159,3 +116,60 @@ int main() {
return A[0] + count;
}
// CHECK-DAG: seen_values: 30
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {function: simple_memcpy_loop}:
? !and
lines: !label simple_memcpy_loop
conditions: "i == 0 || i == 4 || i == 8"
: !value nelems: 16
!value "src[i]": [3, 7, 1]
!where {function: trivial_memcpy_loop}:
? !and
lines: !label trivial_memcpy_loop
conditions: "i == 3 || i == 7 || i == 9 || i == 14 || i == 15"
: !value i: [3, 7, 9, 14, 15]
!value "dest[i-1] == src[i-1]": "true"
!where {function: nonleaf_function_with_loop}:
!and {lines: !label nonleaf_function_with_loop, conditions: "i == 1"}:
!value "dest[0]": 8
!value "dest[1]": 4
!value "dest[2]": 5
!value "src[0]": 8
!value "src[1]": 4
!value "src[2]": 5
!value "src[1] == dest[1]": "true"
!value "src[2] == dest[2]": "true"
!where {function: counting_loop}:
!and {lines: !label counting_loop, conditions: "i == 8 || i == 16"}:
!value i: [8, 16]
!where {function: loop_rotate_test}:
!and {lines: !label loop_rotate_test, conditions: "result == 13"}:
!value "src[count]": 13
!and {lines: !label loop_rotate_test_ret, conditions: "result == 158"}:
!value result: 158
!where {function: loop_vectorize_test}:
? !and
lines: !range [!label loop_vectorize_test, !label loop_vectorize_test_9]
conditions: "count == 4 || count == 8 || count == 12 || count == 16"
: !and {lines: !label loop_vectorize_test_2}:
!value 'tempArray[count] == src[count]': "true"
!and {lines: !label loop_vectorize_test_3}:
!value 'tempArray[count+1] == src[count+1]': "true"
!and {lines: !label loop_vectorize_test_4}:
!value 'tempArray[count+2] == src[count+2]': "true"
!and {lines: !label loop_vectorize_test_5}:
!value 'tempArray[count+3] == src[count+3]': "true"
!and {lines: !label loop_vectorize_test_6}:
!value 'dest[count] == tempArray[count]': "true"
!and {lines: !label loop_vectorize_test_7}:
!value 'dest[count+1] == tempArray[count+1]': "true"
!and {lines: !label loop_vectorize_test_8}:
!value 'dest[count+2] == tempArray[count+2]': "true"
!and {lines: !label loop_vectorize_test_9}:
!value 'dest[count+3] == tempArray[count+3]': "true"
...
*/

View file

@ -1,9 +1,9 @@
// RUN: %clang++ -std=gnu++11 -O2 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
// RUN: %clang++ -std=gnu++11 -O0 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
// REQUIRES: lldb, D136396
// Currently getting intermittent failures on darwin.
@ -16,91 +16,138 @@
__attribute__((optnone))
int test1(int test1_a, int test1_b) {
int test1_result = 0;
// DexLabel('test1_start')
test1_result = test1_a + test1_b; // DexExpectStepOrder(1)
return test1_result; // DexExpectStepOrder(2)
// DexLabel('test1_end')
// !dex_label test1_start
test1_result = test1_a + test1_b;
return test1_result;
// !dex_label test1_end
}
// DexExpectWatchValue('test1_a', 3, from_line=ref('test1_start'), to_line=ref('test1_end'))
// DexExpectWatchValue('test1_b', 4, from_line=ref('test1_start'), to_line=ref('test1_end'))
// DexExpectWatchValue('test1_result', 0, 7, from_line=ref('test1_start'), to_line=ref('test1_end'))
__attribute__((optnone))
int test2(int test2_a, int test2_b) {
int test2_result = test2_a + test2_a + test2_a + test2_a; // DexExpectStepOrder(3)
// DexLabel('test2_start')
return test2_a << 2; // DexExpectStepOrder(4)
// DexLabel('test2_end')
int test2_result = test2_a + test2_a + test2_a + test2_a;
// !dex_label test2_start
return test2_a << 2;
// !dex_label test2_end
}
// DexExpectWatchValue('test2_a', 1, from_line=ref('test2_start'), to_line=ref('test2_end'))
// DexExpectWatchValue('test2_b', 2, from_line=ref('test2_start'), to_line=ref('test2_end'))
// DexExpectWatchValue('test2_result', 4, from_line=ref('test2_start'), to_line=ref('test2_end'))
__attribute__((optnone))
int test3(int test3_a, int test3_b) {
int test3_temp1 = 0, test3_temp2 = 0;
// DexLabel('test3_start')
test3_temp1 = test3_a + 5; // DexExpectStepOrder(5)
test3_temp2 = test3_b + 5; // DexExpectStepOrder(6)
if (test3_temp1 > test3_temp2) { // DexExpectStepOrder(7)
test3_temp1 *= test3_temp2; // DexUnreachable()
// !dex_label test3_start
test3_temp1 = test3_a + 5;
test3_temp2 = test3_b + 5;
if (test3_temp1 > test3_temp2) {
test3_temp1 *= test3_temp2;
}
return test3_temp1; // DexExpectStepOrder(8)
// DexLabel('test3_end')
return test3_temp1;
// !dex_label test3_end
}
// DexExpectWatchValue('test3_a', 5, from_line=ref('test3_start'), to_line=ref('test3_end'))
// DexExpectWatchValue('test3_b', 6, from_line=ref('test3_start'), to_line=ref('test3_end'))
// DexExpectWatchValue('test3_temp1', 0, 10, from_line=ref('test3_start'), to_line=ref('test3_end'))
// DexExpectWatchValue('test3_temp2', 0, 11, from_line=ref('test3_start'), to_line=ref('test3_end'))
unsigned num_iterations = 4;
__attribute__((optnone))
int test4(int test4_a, int test4_b) {
int val1 = 0, val2 = 0;
// DexLabel('test4_start')
// !dex_label test4_start
val1 = (test4_a > test4_b) ? test4_a : test4_b; // DexExpectStepOrder(9)
val1 = (test4_a > test4_b) ? test4_a : test4_b;
val2 = val1;
val2 += val1; // DexExpectStepOrder(10)
val2 += val1;
for (unsigned i=0; i != num_iterations; ++i) { // DexExpectStepOrder(11, 13, 15, 17, 19)
for (unsigned i = 0; i != num_iterations; ++i) {
val1--;
val2 += i;
if (val2 % 2 == 0) // DexExpectStepOrder(12, 14, 16, 18)
if (val2 % 2 == 0)
val2 /= 2;
}
return (val1 > val2) ? val2 : val1; // DexExpectStepOrder(20)
// DexLabel('test4_end')
return (val1 > val2) ? val2 : val1;
// !dex_label test4_end
}
// DexExpectWatchValue('test4_a', 1, from_line=ref('test4_start'), to_line=ref('test4_end'))
// DexExpectWatchValue('test4_b', 9, from_line=ref('test4_start'), to_line=ref('test4_end'))
// DexExpectWatchValue('val1', 0, 9, 8, 7, 6, 5, from_line=ref('test4_start'), to_line=ref('test4_end'))
// DexExpectWatchValue('val2', 0, 9, 18, 9, 10, 5, 7, 10, 5, 9, from_line=ref('test4_start'), to_line=ref('test4_end'))
__attribute__((optnone))
int test5(int test5_val) {
int c = 1; // DexExpectStepOrder(21)
// DexLabel('test5_start')
if (test5_val) // DexExpectStepOrder(22)
c = 5; // DexExpectStepOrder(23)
return c ? test5_val : test5_val; // DexExpectStepOrder(24)
// DexLabel('test5_end')
int c = 1;
// !dex_label test5_start
if (test5_val)
c = 5;
return c ? test5_val : test5_val;
// !dex_label test5_end
}
// DexExpectWatchValue('test5_val', 7, from_line=ref('test5_start'), to_line=ref('test5_end'))
// DexExpectWatchValue('c', 1, 5, from_line=ref('test5_start'), to_line=ref('test5_end'))
__attribute__((optnone))
int main() {
int main_result = 0;
// DexLabel('main_start')
// !dex_label main_start
main_result = test1(3,4);
main_result += test2(1,2);
main_result += test3(5,6);
main_result += test4(1,9);
main_result += test5(7);
return main_result;
// DexLabel('main_end')
// !dex_label main_end
}
// DexExpectWatchValue('main_result', 0, 7, 11, 21, 26, 33, from_line=ref('main_start'), to_line=ref('main_end'))
// CHECK-DAG: seen_values: 154
// CHECK-DAG: correct_step_coverage: 100.0%
// CHECK-DAG: correct_line_score: 100.0%
/*
---
!where {function: test1}:
!and {lines: !range [!label test1_start, !label test1_end]}:
!value test1_a: 3
!value test1_b: 4
!value test1_result: [0, 7]
!step order: [!label test1_start + 1, !label test1_start + 2]
!where {function: test2}:
!and {lines: !range [!label test2_start, !label test2_end]}:
!value test2_a: 1
!value test2_b: 2
!value test2_result: 4
!step order: [!label test2_start - 1, !label test2_start + 1]
!where {function: test3}:
!and {lines: !range [!label test3_start, !label test3_end]}:
!value test3_a: 5
!value test3_b: 6
!value test3_temp1: [0, 10]
!value test3_temp2: [0, 11]
!step order:
- !label test3_start + 1
- !label test3_start + 2
- !label test3_start + 3
- !label test3_end - 1
!step never: [!label test3_start + 4]
!where {function: test4}:
!and {lines: !range [!label test4_start, !label test4_end]}:
!value test4_a: 1
!value test4_b: 9
!value val1: [0, 9, 8, 7, 6, 5]
!value val2: [0, 9, 18, 9, 10, 5, 7, 10, 5, 9]
!step order:
- !label test4_start + 2
- !label test4_start + 4
- !label test4_start + 6
- !label test4_start + 9
- !label test4_start + 6
- !label test4_start + 9
- !label test4_start + 6
- !label test4_start + 9
- !label test4_start + 6
- !label test4_start + 9
- !label test4_start + 6
- !label test4_end - 1
!where {function: test5}:
!and {lines: !range [!label test5_start, !label test5_end]}:
!value test5_val: 7
!value c: [1, 5]
!step order:
- !label test5_start - 1
- !label test5_start + 1
- !label test5_start + 2
- !label test5_start + 3
!where {function: main}:
!and {lines: !range [!label main_start, !label main_end]}:
!value main_result: [0, 7, 11, 21, 26, 33]
...
*/

View file

@ -1,9 +1,9 @@
// RUN: %clang++ -std=gnu++11 -O2 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -v -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -v -- %s | FileCheck %s
// RUN: %clang++ -std=gnu++11 -O0 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
// REQUIRES: lldb
// Currently getting intermittent failures on darwin.
@ -67,31 +67,19 @@ public:
__attribute__((optnone))
A() {
__builtin_memset(this, 0xFF, sizeof(*this));
} //DexLabel('break_0')
// DexExpectWatchValue('a', '-1', on_line=ref('break_0'))
//// Check b is NaN by comparing it to itself.
// DexExpectWatchValue('this->b == this->b', 'false', on_line=ref('break_0'))
// DexExpectWatchValue('_data.a.raw_ptr == -1', 'true', on_line=ref('break_0'))
// DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0'))
// DexExpectWatchValue('_data.a.float_ptr == -1', 'true', on_line=ref('break_0'))
// DexExpectWatchValue('a_global_ptr[0]', 0xcafebabe, on_line=ref('break_0'))
// DexExpectWatchValue('a_global_ptr[1]', 0xfeedbeef, on_line=ref('break_0'))
} // !dex_label break_0
__attribute__((optnone))
~A() {
*getOtherData()->a.long_ptr = 0xADDF00DL;
} //DexLabel('break_1')
// DexExpectWatchValue('_data.a.raw_ptr == a_global_ptr', 'true', on_line=ref('break_1'))
// DexExpectWatchValue('a_global_ptr[0]', 0xaddf00d, on_line=ref('break_1'))
} // !dex_label break_1
__attribute__((optnone))
long getData() {
setSomeData1(B_VALUE, A_VALUE);
setOtherData();
return getOtherData()->a.long_ptr[1]; //DexLabel('break_2')
return getOtherData()->a.long_ptr[1]; // !dex_label break_2
}
// DexExpectWatchValue('_data.b.other_b', 'B_VALUE', on_line=ref('break_2'))
// DexExpectWatchValue('_data.b.other_other_b', 'A_VALUE', on_line=ref('break_2'))
};
} // anonymous namespace
@ -104,3 +92,26 @@ int main() {
}
return result;
}
// CHECK-DAG: seen_values: 11
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label break_0}:
!value a: -1
# Check b is NaN by comparing it to itself.
!value 'this->b == this->b': 'false'
!value '_data.a.raw_ptr == -1': 'true'
!value '_data.a.float_ptr == -1': 'true'
!value '_data.a.float_ptr == -1': 'true'
!value 'a_global_ptr[0]': 0xcafebabe
!value 'a_global_ptr[1]': 0xfeedbeef
!where {lines: !label break_1}:
!value '_data.a.raw_ptr == a_global_ptr': 'true'
!value 'a_global_ptr[0]': 0xaddf00d
!where {lines: !label break_2}:
!value '_data.b.other_b': 'B_VALUE'
!value '_data.b.other_other_b': 'A_VALUE'
...
*/

View file

@ -1,9 +1,9 @@
// RUN: %clang++ -std=gnu++11 -O2 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -v -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -v -- %s | FileCheck %s
// RUN: %clang++ -std=gnu++11 -O0 -g %s -o %t
// RUN: %dexter --fail-lt 1.0 -w \
// RUN: --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script \
// RUN: --binary %t %dexter_lldb_args -- %s | FileCheck %s
// REQUIRES: lldb
// Currently getting intermittent failures on darwin.
@ -27,101 +27,41 @@ unsigned TypeTraits<int4>::MysteryNumber = 3U;
template<typename T>
__attribute__((optnone))
T test1(T x, T y) {
T tmp = x + y; // DexLabel('break_0')
T tmp = x + y; // !dex_label break_0
T tmp2 = tmp + y;
return tmp; // DexLabel('break_1')
return tmp; // !dex_label break_1
}
// DexLimitSteps('1', '1', from_line=ref('break_0'), to_line=ref('break_1'))
//// FIXME: gdb can print this but lldb cannot. Perhaps PR42920?
// \DexExpectWatchValue('TypeTraits<int __attribute__((ext_vector_type(4)))>::NumElements', 4, on_line=ref('break_0'))
// \DexExpectWatchValue('TypeTraits<int __attribute__((ext_vector_type(4)))>::UnusedField', 0xdeadbeef, on_line=ref('break_0'))
// DexExpectWatchValue('x[0]', 1, on_line=ref('break_0'))
// DexExpectWatchValue('x[1]', 2, on_line=ref('break_0'))
// DexExpectWatchValue('x[2]', 3, on_line=ref('break_0'))
// DexExpectWatchValue('x[3]', 4, on_line=ref('break_0'))
// DexExpectWatchValue('y[0]', 5, on_line=ref('break_0'))
// DexExpectWatchValue('y[1]', 6, on_line=ref('break_0'))
// DexExpectWatchValue('y[2]', 7, on_line=ref('break_0'))
// DexExpectWatchValue('y[3]', 8, on_line=ref('break_0'))
// DexExpectWatchValue('tmp[0]', 6, on_line=ref('break_1'))
// DexExpectWatchValue('tmp[1]', 8, on_line=ref('break_1'))
// DexExpectWatchValue('tmp[2]', 10, on_line=ref('break_1'))
// DexExpectWatchValue('tmp[3]', 12, on_line=ref('break_1'))
// DexExpectWatchValue('tmp2[0]', 11, on_line=ref('break_1'))
// DexExpectWatchValue('tmp2[1]', 14, on_line=ref('break_1'))
// DexExpectWatchValue('tmp2[2]', 17, on_line=ref('break_1'))
// DexExpectWatchValue('tmp2[3]', 20, on_line=ref('break_1'))
template<typename T>
__attribute__((optnone))
T test2(T x, T y) {
T tmp = x;
int break_2 = 0; // DexLabel('break_2')
int break_2 = 0; // !dex_label break_2
for (unsigned i = 0; i != TypeTraits<T>::NumElements; ++i) {
tmp <<= 1; // DexLabel('break_3')
tmp <<= 1; // !dex_label break_3
tmp |= y;
}
tmp[0] >>= TypeTraits<T>::MysteryNumber;
return tmp; // DexLabel('break_5')
return tmp; // !dex_label break_5
}
// DexLimitSteps('1', '1', on_line=ref('break_2'))
// DexExpectWatchValue('x[0]', 6, on_line=ref('break_2'))
// DexExpectWatchValue('x[1]', 8, on_line=ref('break_2'))
// DexExpectWatchValue('x[2]', 10, on_line=ref('break_2'))
// DexExpectWatchValue('x[3]', 12, on_line=ref('break_2'))
// DexExpectWatchValue('y[0]', 5, on_line=ref('break_2'))
// DexExpectWatchValue('y[1]', 6, on_line=ref('break_2'))
// DexExpectWatchValue('y[2]', 7, on_line=ref('break_2'))
// DexExpectWatchValue('y[3]', 8, on_line=ref('break_2'))
// DexExpectWatchValue('tmp[0]', 6, on_line=ref('break_2'))
// DexExpectWatchValue('tmp[1]', 8, on_line=ref('break_2'))
// DexExpectWatchValue('tmp[2]', 10, on_line=ref('break_2'))
// DexExpectWatchValue('tmp[3]', 12, on_line=ref('break_2'))
// DexLimitSteps('i', 3, from_line=ref('break_3'), to_line=ref('break_5'))
// DexExpectWatchValue('tmp[0]', 63, on_line=ref('break_3'))
// DexExpectWatchValue('tmp[1]', 94, on_line=ref('break_3'))
// DexExpectWatchValue('tmp[2]', 95, on_line=ref('break_3'))
// DexExpectWatchValue('tmp[3]', 120, on_line=ref('break_3'))
// DexExpectWatchValue('tmp[0]', 15, on_line=ref('break_5'))
template<typename T>
__attribute__((optnone))
T test3(T InVec) {
T result;
for (unsigned i=0; i != TypeTraits<T>::NumElements; ++i)
result[i] = InVec[i]; // DexLabel('break_6')
return result; // DexLabel('break_7')
result[i] = InVec[i]; // !dex_label break_6
return result; // !dex_label break_7
}
// DexLimitSteps('i', '3', from_line=ref('break_6'), to_line=ref('break_7'))
// DexExpectWatchValue('InVec[0]', 15, from_line=ref('break_6'), to_line=ref('break_7'))
// DexExpectWatchValue('InVec[1]', 190, from_line=ref('break_6'), to_line=ref('break_7'))
// DexExpectWatchValue('InVec[2]', 191, from_line=ref('break_6'), to_line=ref('break_7'))
// DexExpectWatchValue('InVec[3]', 248, from_line=ref('break_6'), to_line=ref('break_7'))
// DexExpectWatchValue('result[0]', 15, from_line=ref('break_6'), to_line=ref('break_7'))
// DexExpectWatchValue('result[1]', 190, from_line=ref('break_6'), to_line=ref('break_7'))
// DexExpectWatchValue('result[2]', 191, from_line=ref('break_6'), to_line=ref('break_7'))
// DexExpectWatchValue('result[3]', 248, on_line=ref('break_7'))
template<typename T>
__attribute__((optnone))
T test4(T x, T y) {
for (unsigned i=0; i != TypeTraits<T>::NumElements; ++i)
x[i] = (x[i] > y[i])? x[i] : y[i] + TypeTraits<T>::MysteryNumber; // DexLabel('break_11')
return x; // DexLabel('break_12')
x[i] = (x[i] > y[i])? x[i] : y[i] + TypeTraits<T>::MysteryNumber; // !dex_label break_11
return x; // !dex_label break_12
}
// DexLimitSteps('1', '1', from_line=ref('break_11'), to_line=ref('break_12'))
//// FIXME: lldb won't print this but gdb unexpectedly says it's optimized out, even at O0.
// \DexExpectWatchValue('TypeTraits<int __attribute__((ext_vector_type(4)))>::MysteryNumber', 3, on_line=ref('break_11'))
// DexExpectWatchValue('i', 0, 1, 2, 3, on_line=ref('break_11'))
// DexExpectWatchValue('x[0]', 1, 8, from_line=ref('break_11'), to_line=ref('break_12'))
// DexExpectWatchValue('x[1]', 2, 9, from_line=ref('break_11'), to_line=ref('break_12'))
// DexExpectWatchValue('x[2]', 3, 10, from_line=ref('break_11'), to_line=ref('break_12'))
// DexExpectWatchValue('x[3]', 4, 11, from_line=ref('break_11'), to_line=ref('break_12'))
// DexExpectWatchValue('y[0]', 5, from_line=ref('break_11'), to_line=ref('break_12'))
// DexExpectWatchValue('y[1]', 6, from_line=ref('break_11'), to_line=ref('break_12'))
// DexExpectWatchValue('y[2]', 7, from_line=ref('break_11'), to_line=ref('break_12'))
// DexExpectWatchValue('y[3]', 8, from_line=ref('break_11'), to_line=ref('break_12'))
int main() {
int4 a = (int4){1,2,3,4};
@ -133,3 +73,82 @@ int main() {
tmp += test4(a,b);
return tmp[0];
}
// CHECK-DAG: seen_values: 64
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label break_0}:
## FIXME: gdb can print this but lldb cannot. Perhaps PR42920?
# !value 'TypeTraits<int __attribute__((ext_vector_type(4)))>::NumElements': 4
# !value 'TypeTraits<int __attribute__((ext_vector_type(4)))>::UnusedField': 0xdeadbeef
!value 'x[0]': 1
!value 'x[1]': 2
!value 'x[2]': 3
!value 'x[3]': 4
!value 'y[0]': 5
!value 'y[1]': 6
!value 'y[2]': 7
!value 'y[3]': 8
!where {lines: !label break_1}:
!value 'tmp[0]': 6
!value 'tmp[1]': 8
!value 'tmp[2]': 10
!value 'tmp[3]': 12
!value 'tmp2[0]': 11
!value 'tmp2[1]': 14
!value 'tmp2[2]': 17
!value 'tmp2[3]': 20
!where {lines: !label break_2}:
!value 'x[0]': 6
!value 'x[1]': 8
!value 'x[2]': 10
!value 'x[3]': 12
!value 'y[0]': 5
!value 'y[1]': 6
!value 'y[2]': 7
!value 'y[3]': 8
!value 'tmp[0]': 6
!value 'tmp[1]': 8
!value 'tmp[2]': 10
!value 'tmp[3]': 12
!where {lines: !label break_3, conditions: "i == 3"}:
!value 'tmp[0]': 63
!value 'tmp[1]': 94
!value 'tmp[2]': 95
!value 'tmp[3]': 120
!where {lines: !label break_5}:
!value 'tmp[0]': 15
!where {lines: !label break_6, conditions: "i == 3"}:
!value 'InVec[0]': 15
!value 'InVec[1]': 190
!value 'InVec[2]': 191
!value 'InVec[3]': 248
!value 'result[0]': 15
!value 'result[1]': 190
!value 'result[2]': 191
!where {lines: !label break_7}:
!value 'InVec[0]': 15
!value 'InVec[1]': 190
!value 'InVec[2]': 191
!value 'InVec[3]': 248
!value 'result[0]': 15
!value 'result[1]': 190
!value 'result[2]': 191
!value 'result[3]': 248
!where {lines: !range [!label break_11, !label break_12]}:
## FIXME: lldb won't print this but gdb unexpectedly says it's optimized out, even at O0.
# !value 'TypeTraits<int __attribute__((ext_vector_type(4)))>::MysteryNumber': 3
!and {lines: !label break_11}:
!value 'i': [0, 1, 2, 3]
!value 'x[0]': [1, 8]
!value 'x[1]': [2, 9]
!value 'x[2]': [3, 10]
!value 'x[3]': [4, 11]
!value 'y[0]': 5
!value 'y[1]': 6
!value 'y[2]': 7
!value 'y[3]': 8
...
*/

View file

@ -2,16 +2,25 @@
// UNSUPPORTED: system-windows
//
// RUN: %clang -std=gnu11 -O -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script --binary %t %dexter_lldb_args -- %s \
// RUN: | FileCheck %s
void __attribute__((noinline, optnone)) bar(int *test) {}
int main() {
int test;
test = 23;
bar(&test); // DexLabel('before_bar')
return test; // DexLabel('after_bar')
bar(&test); // !dex_label before_bar
return test; // !dex_label after_bar
}
// DexExpectWatchValue('test', '23', on_line=ref('before_bar'))
// DexExpectWatchValue('test', '23', on_line=ref('after_bar'))
// CHECK-DAG: seen_values: 2
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label before_bar}:
!value test: 23
!where {lines: !label after_bar}:
!value test: 23
...
*/

View file

@ -3,14 +3,15 @@
// UNSUPPORTED: system-windows
//
// RUN: %clang -std=gnu11 -O0 -glldb %s -o %t
// RUN: %dexter --fail-lt 1.0 -w --binary %t %dexter_lldb_args -- %s
// RUN: %dexter -w --use-script --binary %t %dexter_lldb_args -- %s \
// RUN: | FileCheck %s
void init_vla(int size) {
int i;
int vla[size];
for (i = 0; i < size; i++)
vla[i] = size-i;
vla[0] = size; // DexLabel('end_init')
vla[0] = size; // !dex_label end_init
}
int main(int argc, const char **argv) {
@ -18,6 +19,14 @@ int main(int argc, const char **argv) {
return 0;
}
// DexExpectWatchValue('vla[0]', '23', on_line=ref('end_init'))
// DexExpectWatchValue('vla[1]', '22', on_line=ref('end_init'))
// CHECK-DAG: seen_values: 2
// CHECK-DAG: correct_step_coverage: 100.0%
/*
---
!where {lines: !label end_init}:
!value vla:
"[0]": 23
"[1]": 22
...
*/