[SOLVED] TFPHTTPClient.SimpleGet causes SIGILL violation error lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- lbd · 2018-04-04 12:28 Hi all Coming from experience with other programming languages, I started programming in Pascal. I'm working on an application that needs to connect to a REST API but I keep getting stuck at the very beginning with almost zero code. I keep getting SIGILL violation errors. My code: 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 UMain; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, httpprotocol, fphttpclient, fpjson, jsonparser; type  { TFMainForm }   TFMainForm = class(TForm)  buttonConnect: TButton;    eFullAPIUrl: TEdit;    eUsername: TEdit;  ePassword: TEdit;    procedure FormCreate(Sender: TObject);    procedure buttonConnectClick(Sender: TObject);  private   public   end; var  FMainForm: TFMainForm; implementation {$R *.lfm}{ TFMainForm }  procedure TFMainForm.FormCreate(Sender: TObject);  begin   end;    procedure TFMainForm.buttonConnectClick(Sender: TObject);  var    fullUrl, responseStr : string;    responseJSON : TJSONObject;  begin     fullUrl := eFullAPIUrl.text;       responseStr := TFPHTTPClient.SimpleGet(fullUrl);       responseJSON := GetJSON(responseStr) as TJSONObject;  end; end.   Workspace: Lazarus 1.9.0FPC: 3.0.4Running on Raspbian Raspberry Pi (ARM Linux) Could anyone help a newbie out ---------------------------------------------------------------------- rvk · 2018-04-04 12:32 You should first check out what the content of responseStr is right after the SimpleGet. Don't just assume it has a correct JSON (or anything at all). If it's empty then something went wrong. Are you quering a HTTPS url ?? If so, did you install the openssl library correctly? For the RPI I have this in my install script for the ssl stuff: sudo apt-get -y install libssl-dev ---------------------------------------------------------------------- lbd · 2018-04-04 12:47 It throws the error during/after TFPHTTPClient.SimpleGet when getting the responseStr. The error is indeed solved by using a http only website. Https addresses cause the issue. OpenSSL seems to be installed correctly (by default). Do I need to do any manual configuration for Lazarus to let it use OpenSSL? OpenSSL Version 1.0.1t from 3 may 2016 is currently installed. ---------------------------------------------------------------------- rvk · 2018-04-04 12:50 Quote from: lbd on April 04, 2018, 02:47:42 pmOpenSSL seems to be installed correctly (by default). Note that libssl-dev is something different than the standard openssl libraries. It's the development headers etc. Did you do the following command and got the message it was already installed? sudo apt-get install libssl-dev How did you install Laz 1.9.0? ---------------------------------------------------------------------- lbd · 2018-04-04 12:58 Sorry for pressing "Post" too soon I've installed the dev version as you mentioned and rebooted the RPi (just in case) but that didn't help Lazarus 1.9.0 was installed by following this guide: https://www.tweaking4all.com/hardware/raspberry-pi/install-lazarus- pascal-on-raspberry-pi-2/ In this guide it states to do the following commands to build/install lazarus from sources. 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 apt-get updateapt-get install -y libx11-dev libgdk-pixbuf2.0-dev libcairo2-dev gir1.2-coglpango-1.0 libpangox-1.0-dev xorg-dev libgtk2.0-dev libpango1.0-devmkdir /usr/local/lazarus cd /usr/local/lazarussvn co http://svn.freepascal.org/svn/lazarus/trunk source cd sourcemake all OPT=-dFPC_ARMHFmake install OPT=-dFPC_ARMHF PREFIX=/usr/local rm -rf /usr/local/lazarus ---------------------------------------------------------------------- rvk · 2018-04-04 13:02 Quote from: lbd on April 04, 2018, 02:47:42 pmIt throws the error during/after TFPHTTPClient.SimpleGet when getting the responseStr. What error is thrown exactly? What url are you using? (maybe we can test it) ---------------------------------------------------------------------- lbd · 2018-04-04 13:13 Using the following demo REST API url: https://reqres.in/api/users?age=2 For the sake of archiving I will mostly try to copy-paste the error instead of posting an image. Error window with text: 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 Project project1 raised exception class 'External: SIGILL'.At address 75868DE8 After pressing "OK" it returns the assembler window point to: 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 75868DE8 1d0f19ee                 mrc             15, 0, r0, cr9, cr13, {0} In assembly this points to an address after OPENSSL_init and just before OPENSSL_cleanse. Assembler window image: https://imgur.com/a/rzVp8 ---------------------------------------------------------------------- rvk · 2018-04-04 13:22 I'm now installing Laz on a fresh rpi. But I've already found something that could cause it. The debugger GDB. https://www.openssl.org/docs/faq.html#PROG16 https://stackoverflow.com/questions/25708907/ssl-library-init-cause- sigill-when-running-under-gdb What happens if you run without the debugger? Run > Run without debugging ---------------------------------------------------------------------- lbd · 2018-04-04 13:27 Running without debugger didn't cause any SIGILL violation. Is this some kind of bug that isn't in older Lazarus versions? The stackoverflow link states that I could 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 handle SIGILL nostopbut I don't know what this will do with possible future (non false-positive) errors. ---------------------------------------------------------------------- rvk · 2018-04-04 14:10 There is also the option to use an environment setting of OPENSSL_armcap=7 or 0 Not sure if that will solve it. But I tested here with a freshly installed Lazarus trunk and I didn't get the SIGILL. Lazarus 1.9.0 r57601 FPC 3.1.1 arm-linux-gtk2 GDB version: GNU gdb (Raspbian 7.12-6) 7.12.0.20161007-git openssl 1.1.0f-3+deb9u1 armhf You could try a update to get the latest versions. sudo apt-get update sudo apt-get -y upgrade Maybe the latest version of openssl and gdb 7.12-6 play nicer together. 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 uses fphttpclient; procedure TForm1.Button1Click(Sender: TObject);var  fullUrl, responseStr : string;begin   fullUrl := 'https://reqres.in/api/users?age=2';   responseStr := TFPHTTPClient.SimpleGet(fullUrl);   Memo1.Lines.Add(ResponseStr);end; ---------------------------------------------------------------------- lbd · 2018-04-05 07:44 I tried an update and upgrade but that didn't update GDB and OpenSSL. I found a walkthrough on how to update GDB but none about updating OpenSSL (atleast not to update to the most recent version that is Raspbian Jessie compliant): https://www.raspberrypi.org/forums/viewtopic.php?t=104827 I've updated GDB to version 7.12.1 through this guide, however that alone didn't fix the issue. The Raspberry Pi runs on Raspbian Jessie we're currently not able to update it to the latest Stretch version as it might break current in- house dependencies. Could you maybe help me point to the right direction to try?: - Setting the environment setting of OpenSSL to OPENSSL_armcap=7 or 0 - Update OpenSSL to a later version, if possible, for Raspbian Jessie Btw, Thank you so much for the effort in helping me out! ---------------------------------------------------------------------- rvk · 2018-04-05 10:03 Quote from: lbd on April 05, 2018, 09:44:00 am- Update OpenSSL to a later version, if possible, for Raspbian Jessie You could try setting a repository to a newer version but that might screw up other packages too, so it's not advised. Quote from: lbd on April 05, 2018, 09:44:00 am- Setting the environment setting of OpenSSL to OPENSSL_armcap=7 or 0 Easiest solution is to add the following line to ~/.profile at the end Code: [Select]export OPENSSL_armcap=7Logout and log back in and the error message stays away (confirmed with 2016-05-27-raspbian- jessie.img and OpenSSL 1.0.1t and GDB 7.7.1). PS. This is tested with a RPI 3B and should also work for RPI 2 (Arm7). If you still have a RPI 1 (Arm6) you might need to set it to 6. ---------------------------------------------------------------------- Thaddy · 2018-04-05 10:23 Note I see an alarming amount of "issues" with ssl code in any language, not just Lazarus or FreePascal or in your case Jessie vs Stretch. The cause is usually that Openssl and major browsers dropped support for insecure protocols. And this time really fast! within months. You may want to review the exact protocols you are using: these may not be adequate.... The compile failure(s) can simply be caused by a call to something that is no longer there.....A lot has been removed in an openssl standard compile. Anyway: you have to fix this in the proper context. If you are using wrong or deprecated protocols there is no way you can "massage" any programming language to still work as it used to. This is a case of global internet infrastructure. Examples: sslv2/3 tls1.0 but also multiple deprecated low value hashes are no longer supported in openssl and others. Which includes all major browsers. Hence you need to rewrite your code to support current standards, not try and make your old code work......There is a reason for that... ---------------------------------------------------------------------- rvk · 2018-04-05 10:34 Quote from: Thaddy on April 05, 2018, 12:23:48 pmThe compile failure(s) can simply be caused by a call to something that is no longer there.....A lot has been removed in an openssl standard compile.It was not a compile failure. It was an error from GDB debugger while running. OpenSSL 1.0.1t throws an "internal" SIGILL which GDB catches. It's thrown in the initialization of OpenSSL when it queries all the CPU capabilities. It seems to be resolved with newer OpenSSL versions. Adding the OPENSSL_armcap=7 also fixes this for older versions. QuoteAnyway: you have to fix this in the proper context. If you are using wrong or deprecated protocols there is no way you can "massage" any programming language to still work as it used to. This is a case of global internet infrastructure.It had nothing to do with the actual protocols. Just the initialization part of OpenSSL. See the earlier mentioned links: https://www.openssl.org/docs/faq.html#PROG16 https://stackoverflow.com/questions/25708907/ssl-library-init-cause- sigill-when-running-under-gdb It's solved with adding export OPENSSL_armcap=7 to the ~/.profile. Although upgrading to stretch might also be considered a better option. Quote from: Thaddy on April 05, 2018, 12:23:48 pmHence you need to rewrite your code to support current standards, not try and make your old code work......There is a reason for that... For this particular problem, setting OPENSSL_armcap is a perfectly acceptable solution and even advised. QuoteTwo options. Either set explicit capability environment variable in order to bypass the capability query (see corresponding crypto/*cap.c for details). Or configure debugger not to stop upon SIGILL exception, e.g. in gdb case add 'handle SIGILL nostop' to your .gdbinit. ---------------------------------------------------------------------- Thaddy · 2018-04-05 10:57 Rik my comment was a note. Because I see this in real life. I respect your explanation, but really? an environment setting? as a fix? in production? Anyway I am curious to fix this in a proper way. ---------------------------------------------------------------------- rvk · 2018-04-05 11:08 Yeah, my preference would also be to just upgrade to stretch. Just upgrading OpenSSL on jessie could be a pain with all dependencies that come with it and could break other things. The newer OpenSSL versions somehow don't throw a SIGILL anymore on the initialization part to determine the processors capabilities. So it's fixed with those newer versions. It's not something that can be changed in FPC anyway. For this particular combination of GDB debugger and OpenSSL 1.0.1t the only option is to tell it what processor it's dealing with (with the given environment setting). With 1.0.1t  becoming older and older it's just a matter of time until jessie itself (with that version) is so outdated it doesn't work anymore with the newer ssl/tls protocols, like you said, and upgrading becomes inevitable. ---------------------------------------------------------------------- lbd · 2018-04-05 13:47 We know working with this old build does indeed come with issues which will problably just become more and more. Most likely we will change to the latest build within a few months time. For the time being, we will have to work with the environment variable. I myself found the answers and solutions provided by rvk more than good for our situation since we just keep working on an old build (for now). Do you guys mind if I mark this thread as Solved? (if possible). ---------------------------------------------------------------------- rvk · 2018-04-05 14:01 Quote from: lbd on April 05, 2018, 03:47:55 pmDo you guys mind if I mark this thread as Solved? (if possible). That's fine. (you can edit the opening post with solved in the subject)