Commit Graph

2387 Commits

Author SHA1 Message Date
Greg Clayton 529a3d87a7 [NFC] Improve FileSpec internal APIs and usage in preparation for adding caching of resolved/absolute.
Resubmission of https://reviews.llvm.org/D130309 with the 2 patches that fixed the linux buildbot, and new windows fixes.

The FileSpec APIs allow users to modify instance variables directly by getting a non const reference to the directory and filename instance variables. This makes it impossible to control all of the times the FileSpec object is modified so we can clear cached member variables like m_resolved and with an upcoming patch caching if the file is relative or absolute. This patch modifies the APIs of FileSpec so no one can modify the directory or filename instance variables directly by adding set accessors and by removing the get accessors that are non const.

Many clients were using FileSpec::GetCString(...) which returned a unique C string from a ConstString'ified version of the result of GetPath() which returned a std::string. This caused many locations to use this convenient function incorrectly and could cause many strings to be added to the constant string pool that didn't need to. Most clients were converted to using FileSpec::GetPath().c_str() when possible. Other clients were modified to use the newly renamed version of this function which returns an actualy ConstString:

ConstString FileSpec::GetPathAsConstString(bool denormalize = true) const;

This avoids the issue where people were getting an already uniqued "const char *" that came from a ConstString only to put the "const char *" back into a "ConstString" object. By returning the ConstString instead of a "const char *" clients can be more efficient with the result.

The patch:
- Removes the non const GetDirectory() and GetFilename() get accessors
- Adds set accessors to replace the above functions: SetDirectory() and SetFilename().
- Adds ClearDirectory() and ClearFilename() to replace usage of the FileSpec::GetDirectory().Clear()/FileSpec::GetFilename().Clear() call sites
- Fixed all incorrect usage of FileSpec::GetCString() to use FileSpec::GetPath().c_str() where appropriate, and updated other call sites that wanted a ConstString to use the newly returned ConstString appropriately and efficiently.

Differential Revision: https://reviews.llvm.org/D130549
2022-07-28 13:28:26 -07:00
Jim Ingham 27893ff1ad Call WatchpointList::RemoveAll in Target::Destroy.
I noticed that the test TestSetWatchpoint.py was failing every so often
on macOS.  The failure was in the last assert, that after destroying the
SBTarget containing it, the SBWatchpoint was still saying it was valid.

IsValid in this case just meant the watchpoint weak pointer could be turned
into a shared pointer.  The watchpoint shared pointers have two strong references
in general, one to the "Target::m_last_created_watchpoint", and one in the
Target::m_watchpoint_list.  Target::Destroy reset the last created watchpoint
but neglected to call RemoveAll on the watchpoint list (it does the analogous
work for the internal & external breakpoint lists...)  This patch does the
equivalent cleanup for the watchpoint list.
2022-07-27 15:15:05 -07:00
Jakob Johnson dde3cf2e83 [trace] Add instruction control flow kind to JSON trace dumper's output
D128477 adds a '-k' flag which displays each instruction's control flow in the `thread trace dump instructions` command's non-json  output (ie no '-j' or '-J' flag)
This diff adds the instruction control flow kind to the `thread trace dump instructions` command's JSON output (ie '-j' or '-J' flag)

Test Plan:
Confirm "controlFlowKind" is present in JSON when '-k' is provided
```
(lldb) thread trace dump instructions -J -k
[
  {                                                                                                                                                                                                                                                                                 [141/1952]
    "id": 7755,
    "loadAddress": "0x400868",
    "module": "test.out",
    "symbol": "main",
    "mnemonic": "jmp",
    "controlFlowKind": "jump",
    "source": "/home/jakobjohnson/jakob-dev/test.cpp",
    "line": 41,
    "column": 29
  },
  {
    "id": 7753,
    "loadAddress": "0x7ffff7b54dab",
    "module": "libstdc++.so.6",
    "symbol": "std::ostream::flush()",
    "mnemonic": "retq",
    "controlFlowKind": "return"
  },
  {
    "id": 7752,
    "loadAddress": "0x7ffff7b54daa",
    "module": "libstdc++.so.6",
    "symbol": "std::ostream::flush()",
    "mnemonic": "popq",
    "controlFlowKind": "other"
  },
  ...
]
```
Confirm "controlFlowKind" is not present when '-k' isn't provided
```
(lldb) thread trace dump instructions -J
[
  {
    "id": 7755,
    "loadAddress": "0x400868",
    "module": "test.out",
    "symbol": "main",
    "mnemonic": "jmp",
    "source": "/home/jakobjohnson/jakob-dev/test.cpp",
    "line": 41,
    "column": 29
  },
  {
    "id": 7753,
    "loadAddress": "0x7ffff7b54dab",
    "module": "libstdc++.so.6",
    "symbol": "std::ostream::flush()",
    "mnemonic": "retq"
  },
  {
    "id": 7752,
    "loadAddress": "0x7ffff7b54daa",
    "module": "libstdc++.so.6",
    "symbol": "std::ostream::flush()",
    "mnemonic": "popq"
  },
```

Differential Revision: https://reviews.llvm.org/D130607
2022-07-27 05:23:59 -07:00
Walter Erquinigo 4f676c2599 [trace][intel pt] Introduce wall clock time for each trace item
- Decouple TSCs from trace items
- Turn TSCs into events just like CPUs. The new name is HW clock tick, wich could be reused by other vendors.
- Add a GetWallTime that returns the wall time that the trace plug-in can infer for each trace item.
- For intel pt, we are doing the following interpolation: if an instruction takes less than 1 TSC, we use that duration, otherwise, we assume the instruction took 1 TSC. This helps us avoid having to handle context switches, changes to kernel, idle times, decoding errors, etc. We are just trying to show some approximation and not the real data. For the real data, TSCs are the way to go. Besides that, we are making sure that no two trace items will give the same interpolation value. Finally, we are using as time 0 the time at which tracing started.

Sample output:

```
(lldb) r
Process 750047 launched: '/home/wallace/a.out' (x86_64)
Process 750047 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
    frame #0: 0x0000000000402479 a.out`main at main.cpp:29:20
   26   };
   27
   28   int main() {
-> 29     std::vector<int> vvv;
   30     for (int i = 0; i < 100; i++)
   31       vvv.push_back(i);
   32
(lldb) process trace start -s 64kb -t --per-cpu
(lldb) b 60
Breakpoint 2: where = a.out`main + 1689 at main.cpp:60:23, address = 0x0000000000402afe
(lldb) c
Process 750047 resuming
Process 750047 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 2.1
    frame #0: 0x0000000000402afe a.out`main at main.cpp:60:23
   57     map<int, int> m;
   58     m[3] = 4;
   59
-> 60     map<string, string> m2;
   61     m2["5"] = "6";
   62
   63     std::vector<std::string> vs = {"2", "3"};
(lldb) thread trace dump instructions -t -f -e thread #1: tid = 750047
    0: [379567.000 ns] (event) HW clock tick [48599428476224707]
    1: [379569.000 ns] (event) CPU core changed [new CPU=2]
    2: [390487.000 ns] (event) HW clock tick [48599428476246495]
    3: [1602508.000 ns] (event) HW clock tick [48599428478664855]
    4: [1662745.000 ns] (event) HW clock tick [48599428478785046]
  libc.so.6`malloc
    5: [1662746.995 ns] 0x00007ffff7176660    endbr64
    6: [1662748.991 ns] 0x00007ffff7176664    movq   0x32387d(%rip), %rax      ;  + 408
    7: [1662750.986 ns] 0x00007ffff717666b    pushq  %r12
    8: [1662752.981 ns] 0x00007ffff717666d    pushq  %rbp
    9: [1662754.977 ns] 0x00007ffff717666e    pushq  %rbx
    10: [1662756.972 ns] 0x00007ffff717666f    movq   (%rax), %rax
    11: [1662758.967 ns] 0x00007ffff7176672    testq  %rax, %rax
    12: [1662760.963 ns] 0x00007ffff7176675    jne    0x9c7e0                   ; <+384>
    13: [1662762.958 ns] 0x00007ffff717667b    leaq   0x17(%rdi), %rax
    14: [1662764.953 ns] 0x00007ffff717667f    cmpq   $0x1f, %rax
    15: [1662766.949 ns] 0x00007ffff7176683    ja     0x9c730                   ; <+208>
    16: [1662768.944 ns] 0x00007ffff7176730    andq   $-0x10, %rax
    17: [1662770.939 ns] 0x00007ffff7176734    cmpq   $-0x41, %rax
    18: [1662772.935 ns] 0x00007ffff7176738    seta   %dl
    19: [1662774.930 ns] 0x00007ffff717673b    jmp    0x9c690                   ; <+48>
    20: [1662776.925 ns] 0x00007ffff7176690    cmpq   %rdi, %rax
    21: [1662778.921 ns] 0x00007ffff7176693    jb     0x9c7b0                   ; <+336>
    22: [1662780.916 ns] 0x00007ffff7176699    testb  %dl, %dl
    23: [1662782.911 ns] 0x00007ffff717669b    jne    0x9c7b0                   ; <+336>
    24: [1662784.906 ns] 0x00007ffff71766a1    movq   0x3236c0(%rip), %r12      ;  + 24
(lldb) thread trace dump instructions -t -f -e -J -c 4
[
  {
    "id": 0,
    "timestamp_ns": "379567.000000",
    "event": "HW clock tick",
    "hwClock": 48599428476224707
  },
  {
    "id": 1,
    "timestamp_ns": "379569.000000",
    "event": "CPU core changed",
    "cpuId": 2
  },
  {
    "id": 2,
    "timestamp_ns": "390487.000000",
    "event": "HW clock tick",
    "hwClock": 48599428476246495
  },
  {
    "id": 3,
    "timestamp_ns": "1602508.000000",
    "event": "HW clock tick",
    "hwClock": 48599428478664855
  },
  {
    "id": 4,
    "timestamp_ns": "1662745.000000",
    "event": "HW clock tick",
    "hwClock": 48599428478785046
  },
  {
    "id": 5,
    "timestamp_ns": "1662746.995324",
    "loadAddress": "0x7ffff7176660",
    "module": "libc.so.6",
    "symbol": "malloc",
    "mnemonic": "endbr64"
  },
  {
    "id": 6,
    "timestamp_ns": "1662748.990648",
    "loadAddress": "0x7ffff7176664",
    "module": "libc.so.6",
    "symbol": "malloc",
    "mnemonic": "movq"
  },
  {
    "id": 7,
    "timestamp_ns": "1662750.985972",
    "loadAddress": "0x7ffff717666b",
    "module": "libc.so.6",
    "symbol": "malloc",
    "mnemonic": "pushq"
  },
  {
    "id": 8,
    "timestamp_ns": "1662752.981296",
    "loadAddress": "0x7ffff717666d",
    "module": "libc.so.6",
    "symbol": "malloc",
    "mnemonic": "pushq"
  }
]
```

Differential Revision: https://reviews.llvm.org/D130054
2022-07-26 12:05:23 -07:00
Jim Ingham 8b7775a472 StackFrame::GetValueObjectForFrameVariable holds the StackFrame lock too long.
This can cause a deadlock if other threads use the common pattern of
"lock the StackFrameList, get a frame, lock the StackFrame."

Differential Revision: https://reviews.llvm.org/D130524
2022-07-26 10:13:19 -07:00
Slava Gurevich 4871dfc64e [LLDB][NFC][Reliability] Fix uninitialized variables from Coverity scan. Part 2
Improve LLDB reliability by fixing the following "uninitialized variables" static code inspection warnings from
scan.coverity.com:

1476275, 1274012, 1455035, 1364789, 1454282
1467483, 1406152, 1406255, 1454837, 1454416
1467446, 1462022, 1461909, 1420566, 1327228
1367767, 1431254, 1467299, 1312678, 1431780
1454731, 1490403

Differential Revision: https://reviews.llvm.org/D130528
2022-07-25 20:52:45 -07:00
Slava Gurevich 9877159dd6 Revert "[LLDB][NFC][Reliability] Fix uninitialized variables from Coverity scan. Part 2"
This reverts commit b9aedd94e6.
2022-07-25 18:23:19 -07:00
Slava Gurevich b9aedd94e6 [LLDB][NFC][Reliability] Fix uninitialized variables from Coverity scan. Part 2
Improve LLDB reliability by fixing the following "uninitialized variables" static code inspection warnings from
scan.coverity.com:

1476275, 1274012, 1455035, 1364789, 1454282
1467483, 1406152, 1406255, 1454837, 1454416
1467446, 1462022, 1461909, 1420566, 1327228
1367767, 1431254, 1467299, 1312678, 1431780
1454731, 1490403

Differential Revision: https://reviews.llvm.org/D130528
2022-07-25 16:40:57 -07:00
Nico Weber 1b4b12a340 Revert "[NFC] Improve FileSpec internal APIs and usage in preparation for adding caching of resolved/absolute." and follow-ups
This reverts commit 9429b67b8e.

It broke the build on Windows, see comments on https://reviews.llvm.org/D130309

It also reverts these follow-ups:

Revert "Fix buildbot breakage after https://reviews.llvm.org/D130309."
This reverts commit f959d815f4.

Revert "Fix buildbot breakage after https://reviews.llvm.org/D130309."
This reverts commit 0bbce7a4c2.

Revert "Cache the value for absolute path in FileSpec."
This reverts commit dabe877248.
2022-07-23 12:35:48 -04:00
Dmitri Gribenko cd9a5cfd2e Use the range-based overload of llvm::sort where possible
Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D130403
2022-07-23 15:13:25 +02:00
Greg Clayton 9429b67b8e [NFC] Improve FileSpec internal APIs and usage in preparation for adding caching of resolved/absolute.
The FileSpect APIs allow users to modify instance variables directly by getting a non const reference to the directory and filename instance variables. This makes it impossibly to control all of the times the FileSpec object is modified so we can clear the cache. This patch modifies the APIs of FileSpec so no one can modify the directory or filename directly by adding set accessors and by removing the get accessors that are non const.

Many clients were using FileSpec::GetCString(...) which returned a unique C string from a ConstString'ified version of the result of GetPath() which returned a std::string. This caused many locations to use this convenient function incorrectly and could cause many strings to be added to the constant string pool that didn't need to. Most clients were converted to using FileSpec::GetPath().c_str() when possible. Other clients were modified to use the newly renamed version of this function which returns an actualy ConstString:
    ConstString FileSpec::GetPathAsConstString(bool denormalize = true) const;

This avoids the issue where people were getting an already uniqued "const char *" that came from a ConstString only to put the "const char *" back into a "ConstString" object. By returning the ConstString instead of a "const char *" clients can be more efficient with the result.

The patch:
- Removes the non const GetDirectory() and GetFilename() get accessors
- Adds set accessors to replace the above functions: SetDirectory() and SetFilename().
- Adds ClearDirectory() and ClearFilename() to replace usage of the FileSpec::GetDirectory().Clear()/FileSpec::GetFilename().Clear() call sites
- Fixed all incorrect usage of FileSpec::GetCString() to use FileSpec::GetPath().c_str() where appropriate, and updated other call sites that wanted a ConstString to use the newly returned ConstString appropriately and efficiently.

Differential Revision: https://reviews.llvm.org/D130309
2022-07-22 10:12:31 -07:00
Kazu Hirata 360c1111e3 Use llvm::is_contained (NFC) 2022-07-20 09:09:19 -07:00
Jim Ingham 83fab8cee9 Revert "Make hit point counts reliable for architectures that stop before evaluation."
This reverts commit 5778ada8e5.

The watchpoint tests all stall on aarch64-ubuntu bots.  Reverting till I can
get my hands on an system to test this out.
2022-07-18 17:38:43 -07:00
Jim Ingham 4f5707e743 Revert "This is a followup to https://reviews.llvm.org/D129814"
This reverts commit 555ae5b8f5.

Apparently, there's something different about how Linux ARM handles watchpoints,
as all the watchpoint tests seem to stall on the Ubuntu aarch64 bots.

Reverting till I can get my hands on a linux system and see what is
wrong.
2022-07-18 17:37:13 -07:00
Jim Ingham 555ae5b8f5 This is a followup to https://reviews.llvm.org/D129814
That was causing hit counts to be double-counted on x86_64 Linux.
It looks like StopInfoWatchpoint::ShouldStopSynchronous gets called
twice for a give stop on Linux (not on Darwin).  I had taken out the
"have I been called already" check when I reworked this part of the
code because it didn't seem necessary.  Putting that back in because
it looks like it is on some systems.
2022-07-18 16:24:31 -07:00
Jim Ingham 5778ada8e5 Make hit point counts reliable for architectures that stop before evaluation.
Since we want to present the "new & old" values for watchpoint hits, on architectures,
including the ARM family, that stop before the triggering instruction is run, we need
to single step over the instruction before stopping for realz.  This was incorrectly
done directly in the StopInfoWatchpoint::ShouldStop.  That causes problems if more than
one thread stops "for a reason" at the same time as the watchpoint, since the other actions
didn't expect the process to make progress in this part of the execution control machinery.

The correct way to do this is to schedule the step over using ThreadPlans, and then to restore
the stop info after that plan stops, so that the rest of the stop info actions can happen when
all the other threads have handled their immediate actions as well.

Differential Revision: https://reviews.llvm.org/D129814
2022-07-18 14:36:32 -07:00
Kazu Hirata 5cff5142a8 Use value instead of getValue (NFC) 2022-07-15 20:03:13 -07:00
Martin Storsjö a1568fa278 [lldb] Silence a GCC warning about missing returns after a fully covered switch. NFC. 2022-07-13 23:57:01 +03:00
ymeng 0466d1df23 [trace][intel pt] Support dumping the trace info in json
Thanks to ymeng@fb.com for coming up with this change.

`thread trace dump info` can dump some metrics that can be useful for
analyzing the performance and quality of a trace. This diff adds a --json
option for dumping this information in json format that can be easily
understood my machines.

Differential Revision: https://reviews.llvm.org/D129332
2022-07-13 12:26:11 -07:00
Walter Erquinigo 4a843d9282 [trace][intel pt] Create a CPU change event and expose it in the dumper
Thanks to fredzhou@fb.com for coming up with this feature.

When tracing in per-cpu mode, we have information of in which cpu we are execution each instruction, which comes from the context switch trace. This diff makes this information available as a `cpu changed event`, which an additional accessor in the cursor `GetCPU()`. As cpu changes are very infrequent, any consumer should listen to cpu change events instead of querying the actual cpu of a trace item. Once a cpu change event is seen, the consumer can invoke GetCPU() to get that information. Also, it's possible to invoke GetCPU() on an arbitrary instruction item, which will return the last cpu seen. However, this call is O(logn) and should be used sparingly.

Manually tested with a sample program that starts on cpu 52, then goes to 18, and then goes back to 52.

Differential Revision: https://reviews.llvm.org/D129340
2022-07-13 12:26:11 -07:00
Walter Erquinigo dbc0cb0198 [trace] Avoid a crash in the dumper when disassembling fails
In rare situations, disassemblying would fail that produce an invalid
InstructionSP object. We need to check that it's valid before using.

With this change, now the dumper doesn't crash with dumping instructions of
ioctl. In fact, it now dumps this output

 {
    "id": 6135,
    "loadAddress": "0x7f4bfe5c7515",
    "module": "libc.so.6",
    "symbol": "ioctl",
    "source": "glibc/2.34/src/glibc-2.34/sysdeps/unix/syscall-template.S",
    "line": 120,
    "column": 0
 }

Anyway, we need to investigate why the diassembler failed disassembling that
instruction. From over 2B instructions I was disassembling today, just this
one failed, so this could be a bug in LLVM's core disassembler.

Differential Revision: https://reviews.llvm.org/D129588
2022-07-12 16:23:03 -07:00
Walter Erquinigo ad7bcda940 [trace] Add a flag to the decoder to output the instruction type
To build complex binding upon instruction trace, additional metadata 'instruction type' is needed.

This diff has followings:
 - Add a flag -k  / --kind for instruction dump
 - Remove SetGranularity and SetIgnoreErros from Trace cursor

Sample output:

```
(lldb) thread trace dump instruction -k
thread #1: tid = 3198805
  libc.so.6`_IO_puts + 356
    2107: 0x00007ffff7163594 (    return)     retq
    2106: 0x00007ffff7163592 (     other)     popq   %r13
    2105: 0x00007ffff7163590 (     other)     popq   %r12
    2104: 0x00007ffff716358f (     other)     popq   %rbp
    2103: 0x00007ffff716358e (     other)     popq   %rbx
    2102: 0x00007ffff716358c (     other)     movl   %ebx, %eax
    2101: 0x00007ffff7163588 (     other)     addq   $0x8, %rsp
    2100: 0x00007ffff7163570 ( cond jump)     je     0x89588                   ; <+344>
    2099: 0x00007ffff716356e (     other)     decl   (%rdx)
    2098: 0x00007ffff7163565 ( cond jump)     je     0x8956e                   ; <+318>
    2097: 0x00007ffff716355e (     other)     cmpl   $0x0, 0x33c02b(%rip)      ; __libc_multiple_threads
    2096: 0x00007ffff7163556 (     other)     movq   $0x0, 0x8(%rdx)
    2095: 0x00007ffff7163554 ( cond jump)     jne    0x89588                   ; <+344>
    2094: 0x00007ffff7163550 (     other)     subl   $0x1, 0x4(%rdx)
    2093: 0x00007ffff7163549 (     other)     movq   0x88(%rbp), %rdx
    2092: 0x00007ffff7163547 ( cond jump)     jne    0x89588                   ; <+344>
    2091: 0x00007ffff7163540 (     other)     testl  $0x8000, (%rbp)           ; imm = 0x8000
    2090: 0x00007ffff716353c (     other)     cmovaq %rax, %rbx
    2089: 0x00007ffff7163535 (     other)     cmpq   $0x7fffffff, %rbx         ; imm = 0x7FFFFFFF
    2088: 0x00007ffff7163530 (     other)     movl   $0x7fffffff, %eax         ; imm = 0x7FFFFFFF
```

Reviewed By: wallace

Differential Revision: https://reviews.llvm.org/D128477
2022-07-12 16:23:03 -07:00
Zequan Wu b74a01a80b Reland "[LLDB][NFC] Decouple dwarf location table from DWARFExpression."
This reland 227dffd0b6 and
562c3467a6 with failed api tests fixed by keeping
function base file addres in DWARFExpressionList.
2022-07-12 10:54:24 -07:00
Jonas Devlieghere e4c5bca597
Revert "[LLDB][NFC] Decouple dwarf location table from DWARFExpression."
This reverts commit 227dffd0b6 and its
follow up 562c3467a6 because it breaks a
bunch of tests on GreenDragon:

https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/45155/
2022-07-07 16:36:10 -07:00
Zequan Wu 227dffd0b6 [LLDB][NFC] Decouple dwarf location table from DWARFExpression.
Differential Revision: https://reviews.llvm.org/D125509
2022-07-07 10:26:58 -07:00
Jim Ingham b8e0b5a071 Threads which hit a breakpoint but fail the condition are considered
not to be hit.  But another thread might be hit at the same time and
actually stop.  So we have to be sure to switch the first thread's
stop info to eStopReasonNone or we'll report a hit when the condition
failed, which is confusing.

Differential Revision: https://reviews.llvm.org/D128776
2022-06-30 11:43:59 -07:00
Walter Erquinigo a7d6c3effe [trace] Make events first class items in the trace cursor and rework errors
We want to include events with metadata, like context switches, and this
requires the API to handle events with payloads (e.g. information about
such context switches). Besides this, we want to support multiple
similar events between two consecutive instructions, like multiple
context switches. However, the current implementation is not good for this because
we are defining events as bitmask enums associated with specific
instructions. Thus, we need to decouple instructions from events and
make events actual items in the trace, just like instructions and
errors.

- Add accessors in the TraceCursor to know if an item is an event or not
- Modify from the TraceDumper all the way to DecodedThread to support
- Renamed the paused event to disabled.
- Improved the tsc handling logic. I was using an API for getting the tsc from libipt, but that was an overkill that should be used when not processing events manually, but as we are already processing events, we can more easily get the tscs.
event items. Fortunately this simplified many things
- As part of this refactor, I also fixed and long stating issue, which is that some non decoding errors were being inserted in the decoded thread. I changed this so that TraceIntelPT::Decode returns an error if the decoder couldn't be set up proplerly. Then, errors within a trace are actual anomalies found in between instrutions.

All test pass

Differential Revision: https://reviews.llvm.org/D128576
2022-06-29 09:19:51 -07:00
Walter Erquinigo f91d82816f [trace] Improve the TraceCursor iteration API
The current way ot traversing the cursor is a bit uncommon and it can't handle empty traces, in fact, its invariant is that it shold always point to a valid item. This diff simplifies the cursor API and allows it to point to invalid items, thus being able to handle empty traces or to know it ran out of data.

- Removed all the granularity functionalities, because we are not actually making use of that. We can bring them back when they are actually needed.
- change the looping logic to the following:

```
  for (; cursor->HasValue(); cursor->Next()) {
     if (cursor->IsError()) {
       .. do something for error
       continue;
     }
     .. do something for instruction
  }

```

- added a HasValue method that can be used to identify if the cursor ran out of data, the trace is empty, or the user tried to move to an invalid position via SetId() or Seek()
- made several simplifications to severals parts of the code.

Differential Revision: https://reviews.llvm.org/D128543
2022-06-28 16:50:12 -07:00
Kazu Hirata 96d1b4ddb2 [lld] Don't use Optional::hasValue (NFC)
This patch replaces x.hasValue() with x where x is contextually
convertible to bool.
2022-06-26 19:29:40 -07:00
Kazu Hirata 3b7c3a654c Revert "Don't use Optional::hasValue (NFC)"
This reverts commit aa8feeefd3.
2022-06-25 11:56:50 -07:00
Kazu Hirata aa8feeefd3 Don't use Optional::hasValue (NFC) 2022-06-25 11:55:57 -07:00
Walter Erquinigo b8dcd0ba26 [NFC][lldb][trace] Rename trace session to trace bundle
As previously discussed with @jj10306, we didn't really have a name for
the post-mortem (or offline) trace session representation, which is in
fact a folder with a bunch of files. We decided to call this folder
"trace bundle", and the main JSON file in it "trace bundle description
file". This naming is pretty decent, so I'm refactoring all the existing
code to account for that.

Differential Revision: https://reviews.llvm.org/D128484
2022-06-24 08:41:33 -07:00
Jim Ingham a1f20da315 The help string for stop-on-shared-library-load was copied to stop-on-exec.
Fix it so it says it does what it does.
2022-06-23 13:54:50 -07:00
Walter Erquinigo efbfde0dd0 [trace] Add an option to dump instructions in json and to a file
In order to provide simple scripting support on top of instruction traces, a simple solution is to enhance the `dump instructions` command and allow printing in json and directly to a file. The format is verbose and not space efficient, but it's not supposed to be used for really large traces, in which case the TraceCursor API is the way to go.

- add a -j option for printing the dump in json
- add a -J option for pretty printing the json output
- add a -F option for specifying an output file
- add a -a option for dumping all the instructions available starting at the initial point configured with the other flags
- add tests for all cases
- refactored the instruction dumper and abstracted the actual "printing" logic. There are two writer implementations: CLI and JSON. This made the dumper itself much more readable and maintanable

sample output:

```
(lldb) thread trace dump instructions  -t -a --id 100 -J
[
  {
    "id": 100,
    "tsc": "43591204528448966"
    "loadAddress": "0x407a91",
    "module": "a.out",
    "symbol": "void std::deque<Foo, std::allocator<Foo>>::_M_push_back_aux<Foo>(Foo&&)",
    "mnemonic": "movq",
    "source": "/usr/include/c++/8/bits/deque.tcc",
    "line": 492,
    "column": 30
  },
  ...
```

Differential Revision: https://reviews.llvm.org/D128316
2022-06-22 11:14:22 -07:00
Alvin Wong 2bae956057 [lldb] Resolve exe location for `target create`
This fixes an issue that, when you start lldb or use `target create`
with a program name which is on $PATH, or not specify the .exe suffix of
a program in the working directory on Windows, you get a confusing
error, for example:

    (lldb) target create notepad
    error: 'C:\WINDOWS\SYSTEM32\notepad.exe' doesn't contain any 'host'
    platform architectures: i686, x86_64, i386, i386

Fixes https://github.com/mstorsjo/llvm-mingw/issues/265

Reviewed By: DavidSpickett

Differential Revision: https://reviews.llvm.org/D127436
2022-06-22 17:16:05 +03:00
Jonas Devlieghere c866f8544c
[lldb] Add a setting to specify the preferred dynamic class info extractor o
Add a setting to configure how LLDB parses dynamic Objective-C class
metadata. By default LLDB will choose the most appropriate method for
the target OS.

Differential revision: https://reviews.llvm.org/D128312
2022-06-21 18:51:39 -07:00
Kazu Hirata ed8fceaa09 Don't use Optional::getValue (NFC) 2022-06-20 23:35:53 -07:00
Jakob Johnson 50f9367960 Add LoadTraceFromFile to SBDebugger and SBTrace
Add trace load functionality to SBDebugger via the `LoadTraceFromFile` method.
Update intelpt test case class to have `testTraceLoad` method so we can take advantage of
the testApiAndSB decorator to test both the CLI and SB without duplicating code.

Differential Revision: https://reviews.llvm.org/D128107
2022-06-20 11:54:47 -07:00
Kazu Hirata aa88161b37 [lldb] Use value_or instead of getValueOr (NFC) 2022-06-19 09:12:01 -07:00
Jim Ingham f22db1fabf Fix StopInfoBreakpoint::ShouldNotify when a callback deletes the site we hit.
When we hit a breakpoint site all of whose owners are internal, we don't
broadcast that event to the public event queue.  However, we were checking
whether that was true in the ShouldNotify method, which gets run after the
breakpoint callbacks get run.  If the breakpoint callback deletes the site
we just hit, we no longer have the information to make that determination.

This patch just gathers the "was all internal" fact when the StopInfoBreakpoint
gets made, which happens before anyone has a chance to delete the site, and then
uses that cached value.

This bug was causing a couple of tests (including TestStopAtEntry.py) to fail
when using new the macOS Ventura dyld support.

Differential Revision: https://reviews.llvm.org/D127997
2022-06-16 11:54:11 -07:00
Walter Erquinigo ea37cd52d1 [trace][intelpt] Support system-wide tracing [22] - Some final touches
Having a member variable TraceIntelPT * makes it look as if it was
optional. I'm using instead a weak_ptr to indicate that it's not
optional and the object is under the ownership of TraceIntelPT.

Besides that, I've simplified the Perf aux and data buffers copying by
using vector.insert.

I'm also renaming Lookup2 to Lookup. The 2 in the name is confusing.

Differential Revision: https://reviews.llvm.org/D127881
2022-06-16 11:42:22 -07:00
Walter Erquinigo 6a5355e8a1 [trace][intelpt] Support system-wide tracing [20] - Rename some fields in the schema
As discusses offline with @jj10305, we are updating some naming used throughout the code, specially in the json schema

- traceBuffer -> iptTrace
- core -> cpu

Differential Revision: https://reviews.llvm.org/D127817
2022-06-16 11:42:22 -07:00
Walter Erquinigo 561a61fb26 [trace][intelpt] Support system-wide tracing [18] - some more improvements
This applies the changes requested for diff 12.

- use DenseMap<ConstString, _> instead of std::unordered_map<ConstString, _>, which is more idiomatic and possibly performant.
- deduplicate some code in Trace.cpp by using helper functions for fetching in maps
- stop using size and offset when fetching binary data, because we in fact read the entire buffers all the time. If we ever need streaming, we can implement it then. Now, the size is used only to check that we are getting the correct amount of data. This is useful because in some cases determining the size doesn't involve fetching the actual data.
- added back the x86_64 macro to the perf tests
- added more documentation
- simplified some file handling
- fixed some comments

Differential Revision: https://reviews.llvm.org/D127752
2022-06-16 11:42:21 -07:00
Walter Erquinigo 03cc58ff2a [trace][intelpt] Support system-wide tracing [17] - Some improvements
This improves several things and addresses comments up to the diff [11] in this stack.

- Simplify many functions to receive less parameters that they can identify easily
- Create Storage classes for Trace and TraceIntelPT that can make it easier to reason about what can change with live process refreshes and what cannot.
- Don't cache the perf zero conversion numbers in lldb-server to make sure we get the most up-to-date numbers.
- Move the thread identifaction from context switches to the bundle parser, to leave TraceIntelPT simpler. This also makes sure that the constructor of TraceIntelPT is invoked when the entire data has been checked to be correct.
- Normalize all bundle paths before the Processes, Threads and Modules are created, so that they can assume that all paths are correct and absolute
- Fix some issues in the tests. Now they all pass.
- return the specific instance when constructing PerThread and MultiCore processor tracers.
- Properly implement IntelPTMultiCoreTrace::TraceStart.
- Improve some comments.
- Use the typedef ContextSwitchTrace more often for clarity.
- Move CreateContextSwitchTracePerfEvent to Perf.h as a utility function.
- Synchronize better the state of the context switch and the intel pt
perf events.
- Use a booblean instead of an enum for the PerfEvent state.

Differential Revision: https://reviews.llvm.org/D127456
2022-06-16 11:23:02 -07:00
Walter Erquinigo ff15efc1a7 [trace][intelpt] Support system-wide tracing [16] - Create threads automatically from context switch data in the post-mortem case
For some context, The context switch data contains information of which threads were
executed by each traced process, therefore it's not necessary to specify
them in the trace file.

So this diffs adds support for that automatic feature. Eventually we
could include it to live processes as well.

Differential Revision: https://reviews.llvm.org/D127001
2022-06-16 11:23:02 -07:00
Walter Erquinigo a19fcc2bec [trace][intelpt] Support system-wide tracing [14] - Decode per cpu
This is the final functional patch to support intel pt decoding per cpu.
It works by doing the following:

- First, all context switches are split by tid and sorted in order. This produces a list of continuous executes per thread per core.
- Then, all intel pt subtraces are split by PSB boundaries and assigned to individual thread continuous executions on the same core by doing simple TSC-based comparisons.
- With this, we have, per thread, a sorted list of continuous executions each one with a list of intel pt subtraces. Up to this point, this is really fast because no instructions were actually decoded.
- Then, each thread can be decoded by traversing their continuous executions and intel pt subtraces. An advantage of having these continuous executions is that we can identify if a continuous exexecution doesn't have intel pt data, and thus has a gap in it. We can later to more sofisticated comparisons to identify if within a continuous execution there are gaps.

I'm adding a test as well.

Differential Revision: https://reviews.llvm.org/D126394
2022-06-16 11:23:01 -07:00
Walter Erquinigo 1a3f996972 [trace][intelpt] Support system-wide tracing [13] - Add context switch decoding
- Add the logic that parses all cpu context switch traces and produces blocks of continuous executions, which will be later used to assign intel pt subtraces to threads and to identify gaps. This logic can also identify if the context switch trace is malformed.
- The continuous executions blocks are able to indicate when there were some contention issues when producing the context switch trace. See the inline comments for more information.
- Update the 'dump info' command to show information and stats related to the multicore decoding flow, including timing about context switch decoding.
- Add the logic to conver nanoseconds to TSCs.
- Fix a bug when returning the context switches. Now they data returned makes sense and even empty traces can be returned from lldb-server.
- Finish the necessary bits for loading and saving a multi-core trace bundle from disk.
- Change some size_t to uint64_t for compatibility with 32 bit systems.

Tested by saving a trace session of a program that sleeps 100 times, it was able to produce the following 'dump info' text:

```
(lldb) trace load /tmp/trace3/trace.json                                                                   (lldb) thread trace dump info                                                                              Trace technology: intel-pt

thread #1: tid = 4192415
  Total number of instructions: 1

  Memory usage:
    Total approximate memory usage (excluding raw trace): 2.51 KiB
    Average memory usage per instruction (excluding raw trace): 2573.00 bytes

  Timing for this thread:

  Timing for global tasks:
    Context switch trace decoding: 0.00s

  Events:
    Number of instructions with events: 0
    Number of individual events: 0

  Multi-core decoding:
    Total number of continuous executions found: 2499
    Number of continuous executions for this thread: 102

  Errors:
    Number of TSC decoding errors: 0
```

Differential Revision: https://reviews.llvm.org/D126267
2022-06-16 11:23:01 -07:00
Dave Lee e30c493894 [lldb] Support non-pointer implicit this/self in GetValueForVariableExpressionPath
The `frame variable` command supports an implicit `this`/`self`, allowing a
user to run `v some_field` instead of `v this->some_field`. However, some
languages have non-pointer `this`/`self` types (for example, Swift).

This change adds support for non-pointer implicit `this`/`self`. This is done
by consulting the type of the instance variable. If the type is known to be
non-pointer, the dot operator is used instead of the arrow operator.

The C language of families each have a pointer instance type, which makes
testing of this difficult. Tests for this feature will be done in the Swift
downstream fork, as Swift's `self` is a non-pointer (reference) type.

rdar://82095148

Reviewed By: aprantl

Differential Revision: https://reviews.llvm.org/D127605
2022-06-15 22:04:02 -07:00
Walter Erquinigo fc5ef57c7d [trace][intelpt] Support system-wide tracing [12] - Support multi-core trace load and save
:q!
This diff is massive, but it's because it connects the client with lldb-server
and also ensures that the postmortem case works.

- Flatten the postmortem trace schema. The reason is that the schema has become quite complex due to the new multicore case, which defeats the original purpose of having a schema that could work for every trace plug-in. At this point, it's better that each trace plug-in defines it's own full schema. This means that the only common field is "type".
-- Because of this new approach, I merged the "common" trace load and saving functionalities into the IntelPT one. This simplified the code quite a bit. If we eventually implement another trace plug-in, we can see then what we could reuse.
-- The new schema, which is flattened, has now better comments and is parsed better. A change I did was to disallow hex addresses, because they are a bit error prone. I'm asking now to print the address in decimal.
-- Renamed "intel" to "GenuineIntel" in the schema because that's what you see in /proc/cpuinfo.
- Implemented reading the context switch trace data buffer. I had to do
some refactors to do that cleanly.
-- A major change that I did here was to simplify the perf_event circular buffer reading logic. It was too complex. Maybe the original Intel author had something different in mind.
- Implemented all the necessary bits to read trace.json files with per-core data.
- Implemented all the necessary bits to save to disk per-core trace session.
- Added a test that ensures that parsing and saving to disk works.

Differential Revision: https://reviews.llvm.org/D126015
2022-06-15 13:28:36 -07:00
Walter Erquinigo a0a46473c3 [trace][intelpt] Support system-wide tracing [11] - Read warnings and perf conversion in the client
- Add logging for when the live state of the process is refreshed
- Move error handling of the live state refreshing to Trace from TraceIntelPT. This allows refreshing to fail either at the plug-in level or at the base class level. The error is cached and it can be gotten every time RefreshLiveProcessState is invoked.
- Allow DoRefreshLiveProcessState to handle plugin-specific parameters.
- Add some encapsulation to prevent TraceIntelPT from accessing variables belonging to Trace.

Test done via logging:

```
(lldb) b main
Breakpoint 1: where = a.out`main + 20 at main.cpp:27:20, address = 0x00000000004023d9
(lldb) r
Process 2359706 launched: '/home/wallace/a.out' (x86_64)
Process 2359706 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
    frame #0: 0x00000000004023d9 a.out`main at main.cpp:27:20
   24   };
   25
   26   int main() {
-> 27     std::vector<int> vvv;
   28     for (int i = 0; i < 100000; i++)
   29       vvv.push_back(i);
   30
(lldb) process trace start                                                                                        (lldb) log enable lldb target -F(lldb) n
Process 2359706 stopped
* thread #1, name = 'a.out', stop reason = step over
    frame #0: 0x00000000004023e8 a.out`main at main.cpp:28:12
   25
   26   int main() {
   27     std::vector<int> vvv;
-> 28     for (int i = 0; i < 100000; i++)
   29       vvv.push_back(i);
   30
   31     std::deque<int> dq1 = {1, 2, 3};
(lldb) thread trace dump instructions -c 2 -t                                                                     Trace.cpp:RefreshLiveProcessState                            Trace::RefreshLiveProcessState invoked
TraceIntelPT.cpp:DoRefreshLiveProcessState                   TraceIntelPT found tsc conversion information
thread #1: tid = 2359706
  a.out`std::vector<int, std::allocator<int>>::vector() + 26 at stl_vector.h:395:19
    54: [tsc=unavailable] 0x0000000000403a7c    retq
```

See the logging lines at the end of the dump. They indicate that refreshing happened and that perf conversion information was found.

Differential Revision: https://reviews.llvm.org/D125943
2022-06-15 12:08:00 -07:00