[Lldb-commits] [lldb] 128c0d0 - [intel-pt] Fix existing support in LLDB

Walter Erquinigo via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 31 11:32:52 PDT 2020


Author: Walter Erquinigo
Date: 2020-03-31T11:32:34-07:00
New Revision: 128c0d037d32c929c58d63fd7f324038430f73ba

URL: https://github.com/llvm/llvm-project/commit/128c0d037d32c929c58d63fd7f324038430f73ba
DIFF: https://github.com/llvm/llvm-project/commit/128c0d037d32c929c58d63fd7f324038430f73ba.diff

LOG: [intel-pt] Fix existing support in LLDB

Summary:
//reviews.llvm.org/D33035 added in 2017 basic support for intel-pt. I
plan to improve it and use it to support reverse debugging.

I fixed a couple of issues and now this plugin works again:
1. pythonlib needed to be linked against it for the SB framework.
Linking was failing because of this
2. the decoding functionality was broken because it lacked handling for
instruction events. It seems old versions of libipt, the actual decoding
library, didn't require these, but modern version require it (you can
read more here
https://github.com/intel/libipt/blob/master/doc/howto_libipt.md). These
events signal overflows of the internal PT buffer in the CPU,
enable/disable events of tracing, async cpu events, interrupts, etc.

I ended up refactoring a little bit the code to reduce code duplication.

In another diff I'll implement some basic tests.

This is a simple execution of the library:

(lldb) target create "/data/users/wallace/rr-project/a.out"
Current executable set to '/data/users/wallace/rr-project/a.out' (x86_64).
(lldb) plugin load liblldbIntelFeatures.so
(lldb) b main
Breakpoint 1: where = a.out`main + 8 at test.cpp:10, address = 0x00000000004007fa
(lldb) b test.cpp:14
Breakpoint 2: where = a.out`main + 50 at test.cpp:14, address = 0x0000000000400824
(lldb) r
Process 902754 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
    frame #0: 0x00000000004007fa a.out`main at test.cpp:10
   7    }
   8
   9    int main() {
-> 10     int z = 0;
   11     for(int i = 0; i < 10000; i++)
   12       z += fun(z);
   13

Process 902754 launched: '/data/users/wallace/rr-project/a.out' (x86_64)
(lldb) processor-trace start all
(lldb) c
Process 902754 resuming
Process 902754 stopped
* thread #1, name = 'a.out', stop reason = breakpoint 2.1
    frame #0: 0x0000000000400824 a.out`main at test.cpp:14
   11     for(int i = 0; i < 10000; i++)
   12       z += fun(z);
   13
-> 14     cout << z<< endl;
   15     return 0;
   16   }

(lldb) processor-trace show-instr-log
thread #1: tid=902754
    0x7ffff72299b9 <+9>: addq   $0x8, %rsp
    0x7ffff72299bd <+13>: retq
    0x4007ed <+16>: addl   $0x1, %eax
    0x4007f0 <+19>: leave
    0x4007f1 <+20>: retq
    0x400814 <+34>: addl   %eax, -0x4(%rbp)
    0x400817 <+37>: addl   $0x1, -0x8(%rbp)
    0x40081b <+41>: cmpl   $0x270f, -0x8(%rbp)       ; imm = 0x270F
    0x400822 <+48>: jle    0x40080a                  ; <+24> at test.cpp:12
    0x400822 <+48>: jle    0x40080a                  ; <+24> at test.cpp:12
```

Subscribers: mgorny, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D76872

Added: 
    

Modified: 
    lldb/tools/intel-features/CMakeLists.txt
    lldb/tools/intel-features/intel-pt/Decoder.cpp
    lldb/tools/intel-features/intel-pt/Decoder.h

Removed: 
    


################################################################################
diff  --git a/lldb/tools/intel-features/CMakeLists.txt b/lldb/tools/intel-features/CMakeLists.txt
index aff75d7db334..efba2f74904f 100644
--- a/lldb/tools/intel-features/CMakeLists.txt
+++ b/lldb/tools/intel-features/CMakeLists.txt
@@ -56,6 +56,7 @@ add_lldb_library(lldbIntelFeatures SHARED
 
   LINK_LIBS
     ${FEATURE_LIBS}
+    ${PYTHON_LIBRARY}
   )
 
 # Add link dependencies for python wrapper

diff  --git a/lldb/tools/intel-features/intel-pt/Decoder.cpp b/lldb/tools/intel-features/intel-pt/Decoder.cpp
index 2ce5c985c546..21642c75327a 100644
--- a/lldb/tools/intel-features/intel-pt/Decoder.cpp
+++ b/lldb/tools/intel-features/intel-pt/Decoder.cpp
@@ -564,6 +564,61 @@ void Decoder::InitializePTInstDecoder(
   }
 }
 
+void Decoder::AppendErrorWithOffsetToInstructionList(
+    int errcode, uint64_t decoder_offset, Instructions &instruction_list,
+    lldb::SBError &sberror) {
+  sberror.SetErrorStringWithFormat(
+      "processor trace decoding library: \"%s\"  [decoder_offset] => "
+      "[0x%" PRIu64 "]",
+      pt_errstr(pt_errcode(errcode)), decoder_offset);
+  instruction_list.emplace_back(sberror.GetCString());
+}
+
+void Decoder::AppendErrorWithoutOffsetToInstructionList(
+    int errcode, Instructions &instruction_list, lldb::SBError &sberror) {
+  sberror.SetErrorStringWithFormat("processor trace decoding library: \"%s\"",
+                                   pt_errstr(pt_errcode(errcode)));
+  instruction_list.emplace_back(sberror.GetCString());
+}
+
+int Decoder::AppendErrorToInstructionList(int errcode, pt_insn_decoder *decoder,
+                                          Instructions &instruction_list,
+                                          lldb::SBError &sberror) {
+  uint64_t decoder_offset = 0;
+  int errcode_off = pt_insn_get_offset(decoder, &decoder_offset);
+  if (errcode_off < 0) {
+    AppendErrorWithoutOffsetToInstructionList(errcode, instruction_list,
+                                              sberror);
+    return errcode_off;
+  }
+  AppendErrorWithOffsetToInstructionList(errcode, decoder_offset,
+                                         instruction_list, sberror);
+  return 0;
+}
+
+int Decoder::HandlePTInstructionEvents(pt_insn_decoder *decoder, int errcode,
+                                       Instructions &instruction_list,
+                                       lldb::SBError &sberror) {
+  while (errcode & pts_event_pending) {
+    pt_event event;
+    errcode = pt_insn_event(decoder, &event, sizeof(event));
+    if (errcode < 0)
+      return errcode;
+
+    // The list of events are in
+    // https://github.com/intel/libipt/blob/master/doc/man/pt_qry_event.3.md
+    if (event.type == ptev_overflow) {
+      int append_errcode = AppendErrorToInstructionList(
+          errcode, decoder, instruction_list, sberror);
+      if (append_errcode < 0)
+        return append_errcode;
+    }
+    // Other events don't signal stream errors
+  }
+
+  return 0;
+}
+
 // Start actual decoding of raw trace
 void Decoder::DecodeTrace(struct pt_insn_decoder *decoder,
                           Instructions &instruction_list,
@@ -585,10 +640,8 @@ void Decoder::DecodeTrace(struct pt_insn_decoder *decoder,
 
       int errcode_off = pt_insn_get_offset(decoder, &decoder_offset);
       if (errcode_off < 0) {
-        sberror.SetErrorStringWithFormat(
-            "processor trace decoding library: \"%s\"",
-            pt_errstr(pt_errcode(errcode)));
-        instruction_list.emplace_back(sberror.GetCString());
+        AppendErrorWithoutOffsetToInstructionList(errcode, instruction_list,
+                                                  sberror);
         return;
       }
 
@@ -619,16 +672,22 @@ void Decoder::DecodeTrace(struct pt_insn_decoder *decoder,
           // progress further. Hence, returning in this situation.
           return;
         }
-        sberror.SetErrorStringWithFormat(
-            "processor trace decoding library: \"%s\"  [decoder_offset] => "
-            "[0x%" PRIu64 "]",
-            pt_errstr(pt_errcode(errcode)), new_decoder_offset);
-        instruction_list.emplace_back(sberror.GetCString());
+        AppendErrorWithOffsetToInstructionList(errcode, new_decoder_offset,
+                                               instruction_list, sberror);
         decoder_offset = new_decoder_offset;
       }
     }
 
     while (1) {
+      errcode = HandlePTInstructionEvents(decoder, errcode, instruction_list,
+                                          sberror);
+      if (errcode < 0) {
+        int append_errcode = AppendErrorToInstructionList(
+            errcode, decoder, instruction_list, sberror);
+        if (append_errcode < 0)
+          return;
+        break;
+      }
       errcode = pt_insn_next(decoder, &insn, sizeof(insn));
       if (errcode < 0) {
         if (insn.iclass == ptic_error)

diff  --git a/lldb/tools/intel-features/intel-pt/Decoder.h b/lldb/tools/intel-features/intel-pt/Decoder.h
index 2ae89653df50..ff3e6f34b6a8 100644
--- a/lldb/tools/intel-features/intel-pt/Decoder.h
+++ b/lldb/tools/intel-features/intel-pt/Decoder.h
@@ -245,6 +245,22 @@ class Decoder {
       lldb::SBError &sberror) const;
   void DecodeTrace(struct pt_insn_decoder *decoder,
                    Instructions &instruction_list, lldb::SBError &sberror);
+  int HandlePTInstructionEvents(pt_insn_decoder *decoder, int errcode,
+                                Instructions &instruction_list,
+                                lldb::SBError &sberror);
+
+  int AppendErrorToInstructionList(int errcode, pt_insn_decoder *decoder,
+                                   Instructions &instruction_list,
+                                   lldb::SBError &sberror);
+
+  void AppendErrorWithOffsetToInstructionList(int errcode,
+                                              uint64_t decoder_offset,
+                                              Instructions &instruction_list,
+                                              lldb::SBError &sberror);
+
+  void AppendErrorWithoutOffsetToInstructionList(int errcode,
+                                                 Instructions &instruction_list,
+                                                 lldb::SBError &sberror);
 
   // Function to diagnose and indicate errors during raw trace decoding
   void Diagnose(struct pt_insn_decoder *decoder, int errcode,


        


More information about the lldb-commits mailing list