[Resolved] Unable to "Attach to program" the Gdb debugger on Linux. lazarus / 12-Debugger ---------------------------------------------------------------------- ArminLinder · 2022-03-10 10:04 I have created a small demo (TestDaemonCodeOnly) on how to create daemons on Linux and Windows, see https://wiki.lazarus.freepascal.org/Daemons_and_Services, source code available at https://github.com/arminlinder/Lazarus-FPC-Wiki-Code- Samples/tree/main/TDaemon. On Windows, everything works like intended, including debugging the daemon running in system context. On Linux (Debuan Buster) debugging works in user context, but if I try to attach the debugger to the running daemon I get "Debugger Error" ... "Attach Failed". Version Infos: Lazarus 2.2.0, FPC 3.2.2, x86_64-linux-gtk2, Debian GNU/Linux 10 (buster), GNU gdb (Debian 8.2.1-2+b3) 8.2.1 Any clues what I can do? Thnx, Armin ---------------------------------------------------------------------- Martin_fr · 2022-03-10 17:21 So what is the gdb output? Menu: view > IDE Internals > Debug Output (must be opened *before* trying to attach). ---------------------------------------------------------------------- ArminLinder · 2022-03-10 18:16 Interesting. Didn't think of the debug window. my bad ... The log says: <-file-exec-and-symbols > ^done (gdb) <-gdb-set language pascal> ^done (gdb) &"set print elements 500\n" =cmd-param-changed,param="print elements",value="500" ^done (gdb) &"attach 4532\n" ~"Attaching to process 4532\n" &"ptrace: Operation not permitted.\n" ^error,msg="ptrace: Operation not permitted." (gdb) &"detach\n" &"The program is not being run.\n" ^error,msg="The program is not being run." (gdb) "Operation not permitted" looks promising. Can you guide me how I do give permissions? Many thanks, Armin. ---------------------------------------------------------------------- Cyrax · 2022-03-10 18:28 Check out this link https://stackoverflow.com/questions/22749015/cannot-debug-with-gdb-in- ubuntu/22761033#22761033 ---------------------------------------------------------------------- ArminLinder · 2022-03-10 18:35 The value in ptrace_scope is, unfortunately, already 0 on my system. From what I read here https://www.kernel.org/doc/Documentation/security/Yama.txt, there isn't a lower level of protection. Am I out of luck trying to attach to a running daemon? Armin. ---------------------------------------------------------------------- MarkMLl · 2022-03-10 20:34 Quote from: Nimral on March 10, 2022, 07:35:28 pmThe value in ptrace_scope is, unfortunately, already 0 on my system. From what I read here https://www.kernel.org/doc/Documentation/security/Yama.txt, there isn't a lower level of protection. Am I out of luck trying to attach to a running daemon? What user is your daemon running as? I presume this thread xrefs to your earlier https://forum.lazarus.freepascal.org/index.php/topic,58250.0.html MarkMLl ---------------------------------------------------------------------- ArminLinder · 2022-03-11 11:16 Quote from: MarkMLl on March 10, 2022, 09:34:46 pmI presume this thread xrefs to your earlier https://forum.lazarus.freepascal.org/index.php/topic,58250.0.html Sort of, yes. That one was about Windows, and two nice solutions were suggested which work like a charm. Now I am after the same under Linux. I came across this problem when I tried to update the wiki. Under Linux being able to attach to the running daemon is somewhat less important, because you can - contrary to Windows - start the daemon main routine using the -run parameter directly from Lazarus, and debugging works like with any other application. Nevertheless there may be permission related problems where the daemon code needs to run in the system context to see them, so I wanted to see whether I can attach to the running daemon on Linux too. Give me half an hour or so to find out how I can see under which context daemons run in Linux. Armin. ---------------------------------------------------------------------- ArminLinder · 2022-03-11 12:12 Ok, I finally found Code: [Select]ps -ef which reveals Code: [Select]root     120851      1  0 13:05 ?        00:00:00 /home/linder/Dokumente/Programming/Lazarus-FPC-Wiki-Code- Samples/TDaemon/x86_64-linux/Debug/TestDaemonCodeOnly -r So the dameon is running under the root account. I'll try to log in as root. and/or sudo the Lazarus executable ... ---------------------------------------------------------------------- ArminLinder · 2022-03-11 13:10 Double failure. Debian won't let me log in as root. Ok, try su then. su + root password will give me root@ prompt. Trying to start lazarus- ide gives: Code: [Select](lazarus-ide:2231): Gtk-WARNING **: 13:56:23.561: cannot open display: :0 The easy fix (gksu) has been recently removed from Debian entirely. Great idea, folks. The not so easy fix Code: [Select]pkexec lazarus-ide leads to the same error as above. Stackoverflow https://unix.stackexchange.com/questions/203136/how-do-i-run-gui- applications-as-root-by-using-pkexec suggests I create a "custom action to policykit", I looked into the xml mess for 5 minutes and **puke**. This is absolutely over the top. There may be people loving to drive a 30 ton truck to buy a box of cigarettes, I don't. Period. All subsequent "solutions" in the above article didn't work at all, or led to the same error message. Other suggested solutions from different forums, like using sudo -i oder sudo -H have zero effect. Question: how do I run lazarus-ide as root under Linux?  Armin. ---------------------------------------------------------------------- MarkMLl · 2022-03-11 13:24 Quote from: Nimral on March 11, 2022, 01:12:20 pmSo the dameon is running under the root account. I'll try to log in as root. and/or sudo the Lazarus executable ... I'd have used  ps faux  but that's mainly because it's the command I'm used to using. OK, I'm going to make some comments here that are very much out of line since I'm neither the maintainer of TDaemon nor am I volunteering to become one: in part since I don't have the multiple OSes set up which would be needed, but mainly due to lack of time. It is very unusual these days to see a daemon or background program running as root: in fact it was unusual 20 years ago, and is why current distreaux set up a significant number of extra user and group IDs. As such, either TDaemon's not fit for purpose or you're overlooking a "run as this user" option. unix doctrine originally had it that the correct way to do things was to start a daemon setuid root, open any files etc. that needed elevated privilege, and then to reliquish root and run as e.g. nobody:nogroup: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMANDrpc        132  0.0  0.1  1448  564 ?        S    10:13   0:00 /sbin/rpc.portmapnobody    1254  0.0  0.1 12536  928 ?        S    10:28   0:00  \_ in.identd -P/dev/nullnobody    1255  0.0  0.1 12536  928 ?        S    10:28   0:00      \_ in.identd -P/dev/nulllp       200  0.0  0.1  2088  968 ?        S    10:13   0:00 lpd Waiting  nobody     212  0.0  0.1  1456  640 ?        S    10:13   0:03  \_ /usr/local/ups/sbin/upsmonnobody     213  0.0  0.1  1452  624 ?        S    10:13   0:02 /usr/local/ups/bin/upslog -s apc1000@192.168.1.1 -l /var/log/ups/apc1000@192.168.1.1.logdaemon     217  0.0  0.1  1424  608 ?        S    10:13   0:00 /usr/sbin/atd -b 15 -l 1nobody     275  0.0  0.7  6820 4020 ?        S    10:13   0:00  \_ /usr/sbin/httpdnews       259  0.0  0.5  6156 3016 ?        S    10:13   0:00 /usr/lib/news/bin/innd -p4news       260  0.0  0.2  2204 1216 ?        S    10:13   0:00 /bin/sh /usr/lib/news/bin/rc.newsnews       632  0.0  0.2  2248 1268 ?        S    10:14   0:00  \_ /bin/sh /usr/lib/news/bin/innwatchnews      9321  0.0  0.0  1272  352 ?        S    12:55   0:00      \_ sleep 600nobody     617  0.0  0.6  4636 3512 ?        S    10:14   0:01 /usr/local/nagios/bin/nagios -d /usr/local/nagios/etc/nagios.cfg  That's a truncated listing from a 2000-era Slackware which I happen to have to hand. Unfortunately, due to the inherent risks a number of application frameworks refuse to run programs marked setuid root. As an example, you might find that you can run a Lazarus app with Qt but not with GTK2. Somewhere around 20 years ago, Linux implemented the POSIX capabilities system which allows finer-grained control. So instead of simply setting a program's setuid bit, you use the setcap program to store a program's potential and actual capabilities in the filesystem: the kernel knows that it a binary is changed or moved these are to be revoked. Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i sudo setcap CAP_DAC_OVERRIDE,CAP_NET_BIND_SERVICE,CAP_NET_RAW=p+e  Watchxxx-x86_64-linux-gtk2  Once the program has opened any privileged files etc. that it needs it relinquishes the capabilities using API calls. I use this fairly heavily, hence my (unapplied) contribution at https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/38608 You are likely to find that a program marked setuid or with POSIX capabilities applied will have these attributes cancelled it you attempt to start it using a standard debugger. I have, however, found that starting a program as root using gdbserver and then connecting to it using the Lazarus IDE works well: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i # gdbserver :2345 ./Watchxxx-x86_64-linux-gtk2  I've very rarely used Lazarus's "attach to program" facility, and never across users. I'd definitely not expect it to work if the daemon is running as root and the IDE as an ordinary user. Collected summary: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit WatchxxxSockets; (* This requires that the program be running with sufficient capabilities to be *)(* able to create a unix-domain socket in /var/run and to bind to a port < 1024,*)(* however immediately after these operations it goes to a lot of trouble to    *)(* relinquish as many privileges as possible.                                 *)(*                                                                            *)(*  *   If linked with gtk2, it is not possible to run setuid root but explicit *)(*      capabilities may be added during installation:                          *)(*                                                                            *)(*      # setcap CAP_DAC_OVERRIDE,CAP_NET_BIND_SERVICE,CAP_NET_RAW=p+e *gtk2    *)(*                                                                            *)(*      Note that capabilities are stored as extended attributes, which DO NOT  *)(*      normally accompany a file if it is subsequently copied.                 *)(*                                                                            *)(*  *   If linked with Qt, the program may be run setuid root:                  *)(*                                                                          *)(*      # chown root:root *qt                                                 *)(*      # chmod u+s *qt                                                       *)(*      # chmod g+s *qt                                                       *)(*                                                                            *)(*      or have extra capabilities as above.                                    *)(*                                                                            *)(*  *   In any case, the program may be started by the superuser (i.e. run as   *)(*      root).                                                                *)(*                                                                            *)(*  *   It may be debugged by being run like                                    *)(*                                                                            *)(*      # gdbserver :2345 ./Watchxxx-x86_64-linux-gtk2                        *)(*                                                                            *)(*      with the Lazarus IDE debugger backend set to remote/gdbserver.          *)(*                                                                            *)(* After the ports have been bound, the CAP_DAC_OVERRIDE, CAP_NET_BIND_SERVICE  *)(* and CAP_NET_RAW permitted and effective capabilities are relinquished. If  *)(* the program is running setuid root, then it reverts to the actual user; if   *)(* it is running as root it assumes group and user IDs as given by the          *)(* ownership of the executable, or ID 65534 as ultimate fallback ("nobody" in   *)(* recent Debian releases).                                     MarkMLl.        *)  I'd obviously be happy to contribute my API interface stuff. HTH. MarkMLl ---------------------------------------------------------------------- ArminLinder · 2022-03-11 14:13 Hi Mark, thanks for your input, it showed me the way. Running a daemon as root seems to be a real pain under Linux, and for my purposes this was not at all intentionally, it just happens if one creates the systemd unit (.service file) using the sample that had formerly been suggested in the wiki about writing Lazarus daemons. Under Windows it is the same, but one usually gets away with this, since Windows does not seem to put such harsh restrictions on the debugger: if the debugging user is an administrator, and runs his Lazarus elevated, he has the debugging privilege, and may attach Gdb to a daemon running under SYSTEM, which is still the default unless the installing user takes additional measures when iunstalling the software. It is, however, common practice as well, to run services using a different account, but this is IMHO not a matter of programming, but a matter of system administration Under Linux it seems an exceptionally bad idea to run the daemon as root (though my simple test code seems to work fine ...), so I added a User=.... statement to the .service file, and ran the service under a different user account. Now the "Attach to program" works. I'll leave a note in the wiki. Thanks, Armin. ---------------------------------------------------------------------- MarkMLl · 2022-03-11 15:55 Quote from: Nimral on March 11, 2022, 03:13:33 pmUnder Linux it seems an exceptionally bad idea to run the daemon as root ...and is very rarely needed, particularly now that users and administrators are getting used to udev files which can set hardware ownership and that daemon restarts can be handled by systemd (which of course everybody trusts without reservation). There's a handful of programs on the typical Linux system which have elevated rights: ping, traceroute and sometimes ifconfig come to mind. The only place where I find myself /having/ to use POSIX capabilities is when listening to a low-numbered network port from a manually- started program. MarkMLl