Community
    • Login

    Debugging Npp .exe without a debugger (beginner)

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    15 Posts 5 Posters 1.2k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • EkopalypseE
      Ekopalypse @Victorel Petrovich
      last edited by

      @Victorel-Petrovich said in Debugging Npp .exe without a debugger (beginner):

      Everywhere I read (including 2 ref-s above , and at microsoft) they say OutputDebugString() is for when the app is run from / has a debugger .

      … but it is not limited to be used only by debuggers. Applications like debugview from sysinternals tools can be used to get this output.

      or a pythons script like

      import ctypes
      from ctypes.wintypes import HANDLE, DWORD, BOOL, LPVOID, LPCWSTR, LPHANDLE
      import mmap
      import struct
      import os
      from Npp import console
      console.show()
      
      kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
      
      CreateEventW = kernel32.CreateEventW
      CreateEventW.argtypes = [LPVOID, BOOL, BOOL, LPCWSTR]
      CreateEventW.restype = HANDLE
      
      SetEvent = kernel32.SetEvent
      SetEvent.argtypes = [HANDLE]
      SetEvent.restype = BOOL
      
      WaitForSingleObject = kernel32.WaitForSingleObject
      WaitForSingleObject.argtypes = [HANDLE, DWORD]
      WaitForSingleObject.restype = DWORD
      
      WaitForMultipleObjects = kernel32.WaitForMultipleObjects
      WaitForMultipleObjects.argtypes = [DWORD, LPHANDLE, BOOL, DWORD]
      WaitForMultipleObjects.restype = DWORD
      
      CloseHandle = kernel32.CloseHandle
      CloseHandle.argtypes = [HANDLE]
      CloseHandle.restype = BOOL
      
      BUFFER_READY = kernel32.CreateEventW(None, 0, 0, 'DBWIN_BUFFER_READY')
      DATA_READY = kernel32.CreateEventW(None, 0, 0, 'DBWIN_DATA_READY')
      STOP_DBG_LOOP = kernel32.CreateEventW(None, 0, 0, 'STOP_DBG_LOOP')
      
      HANDLES = (HANDLE * 2)(DATA_READY, STOP_DBG_LOOP)
      buffer = mmap.mmap(0, 4096, "DBWIN_BUFFER", mmap.ACCESS_WRITE)
      CURRENT_NPP_ID = os.getpid()
      
      # Call SetEvent(STOP_DBG_LOOP) to stop the loop,
      # either with a second script or by calling from the PS console
      
      while True:
          SetEvent(BUFFER_READY)
          result = WaitForMultipleObjects(2, HANDLES, False, 0xFFFFFFFF)
          if result == 1:  # STOP_DBG_LOOP received
              break
          elif result == 0:
              buffer.seek(0)
              process_id, = struct.unpack("L", buffer.read(4))
              data = buffer.read(4092)
              if CURRENT_NPP_ID != process_id:  # to prevent seeing PS's own debug strings.
                  if b"\0" in data:
                      data = data[:data.index(b"\0")]
                  print("Process:[{0}] {1}".format(process_id, data.decode().strip()))
          else:
              print('ooppss: {}'.format(result))
              break
      
      CloseHandle(BUFFER_READY)
      CloseHandle(DATA_READY)
      CloseHandle(STOP_DBG_LOOP)
      print('done')
      
      Victorel PetrovichV 1 Reply Last reply Reply Quote 3
      • Victorel PetrovichV
        Victorel Petrovich @Ekopalypse
        last edited by Victorel Petrovich

        @Ekopalypse you’re a wizard

        Victorel PetrovichV 1 Reply Last reply Reply Quote 2
        • Victorel PetrovichV
          Victorel Petrovich @Victorel Petrovich
          last edited by Victorel Petrovich

          I’ve just downloaded DebugView from sysinternals (easy to use), and read in several pages about OutputDebugString().
          So, yes, it’s good if you don’t want to create a console in the app with AllocConsole() like above.
          But then you usually need to prepare the formatted string in advance using sprintf() or similar, then pass to OutputDebugString… (Or write a special function to do it… again extra inserted code or files).
          So printf() is easier to use (at least for most practical cases, IMO), and already familiar.

          Alan KilbornA 1 Reply Last reply Reply Quote 0
          • Alan KilbornA
            Alan Kilborn @Victorel Petrovich
            last edited by

            @Victorel-Petrovich said in Debugging Npp .exe without a debugger (beginner):

            So printf() is easier to use (at least for most practical cases, IMO), and already familiar.

            Really, only because you already have the “console” approach in your rearview mirror.

            If someone didn’t have that, OutputDebugString is easier.

            It’s just a matter of (in very simple terms):

            char buf[1024];
            sprintf(buf, “test”);
            OutputDebugString(buf);

            Victorel PetrovichV 1 Reply Last reply Reply Quote 0
            • Victorel PetrovichV
              Victorel Petrovich @Alan Kilborn
              last edited by Victorel Petrovich

              @Alan-Kilborn said in Debugging Npp .exe without a debugger (beginner):

              It’s just a matter of (in very simple terms):
              char buf[1024];
              sprintf(buf, “test”);
              OutputDebugString(buf);

              But when you have several tens of outputs to write in every function you test… :/

              d390b628-0f66-493e-8f3e-127d0b706c2d-image.png

              Alan KilbornA 1 Reply Last reply Reply Quote 1
              • Alan KilbornA
                Alan Kilborn @Victorel Petrovich
                last edited by Alan Kilborn

                @Victorel-Petrovich said in Debugging Npp .exe without a debugger (beginner):

                But when you have several tens of outputs to write in every function you test

                Hmm, no idea why that’s a problem…

                I think if this is how you’re considering debugging Notepad++ changes you might make…it is going to wear you down fast and you’ll give up trying to make changes.

                Victorel PetrovichV 1 Reply Last reply Reply Quote 1
                • Victorel PetrovichV
                  Victorel Petrovich @Alan Kilborn
                  last edited by Victorel Petrovich

                  @Alan-Kilborn With column-mode editing, and duplication of lines etc, it’s not that bad.
                  Much harder is to understand why I don’t get the results I expect, doing lots of googling , and try again and again.

                  1 Reply Last reply Reply Quote 0
                  • Victorel PetrovichV
                    Victorel Petrovich
                    last edited by

                    Another option, pointed out to me by @Yaron10 on github:
                    printInt(int int2print) and printStr(const TCHAR *str2print)
                    Will output in a message box…
                    Comparable with OutputDebugString in the need to prepare the (complex) string beforehand, but doesn’t require a debugger or allocating a console.
                    https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/src/MISC/Common/Common.cpp#L32
                    (The definitions also hint at how to properly pass the string).

                    PeterJonesP 1 Reply Last reply Reply Quote 0
                    • PeterJonesP PeterJones moved this topic from General Discussion on
                    • PeterJonesP
                      PeterJones @Victorel Petrovich
                      last edited by

                      Topic moved to the newly renamed and refocused “Notepad++ & Plugin Development” category, where it naturally fits (I assumed @Victorel-Petrovich wouldn’t mind it being moved, since he was the one who wanted a specific place to ask such questions).

                      Personally, when I am doing a lot of print-based debugging, I write wrapper functions or #define macros that encapsulate all the formatting into the string, and then call the proper output function with that string, so that I can just have a single line of code for each inline debug print, and I let the complications of definining a dummy buffer variable and the sprintf formatting elsewhere.

                      But really, none of these questions are specific to debugging Notepad++, and is really a generic C/C++ “best way to debug without a debugger, without a console, or similar restriction” question.

                      Victorel PetrovichV 1 Reply Last reply Reply Quote 3
                      • Victorel PetrovichV
                        Victorel Petrovich @PeterJones
                        last edited by

                        @PeterJones said in Debugging Npp .exe without a debugger (beginner):

                        I assumed @Victorel-Petrovich wouldn’t mind it being moved

                        True

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        The Community of users of the Notepad++ text editor.
                        Powered by NodeBB | Contributors