Categories: Digital Logic

Tristate Buffers & Impedance

Learning more about computer architecture has rekindled in me an interest in digital logic. I was perusing the Introduction to Logic Synthesis Using Verilog HDL book when I encountered tristate buffers – one of the less obvious circuit components to me. YouTube proved to be a valuable resource (as it often does) with a variety of explanations about what they are and how they are used. Below is my favorite video on the topic.

I wanted to learn more about the concept of impedance since the high impedance mode is one of the tristate buffer states. Wikipedia’s article on Electrical impedance seemed a bit much for the high level overview I sought. Back on YouTube, I found this video that, while not focussed on digital circuits, was quite interesting. It got me to order a P3 P4400 Kill A Watt Electricity Usage Monitor for myself.


Categories: Java

Checking Symbol Availability on Windows OpenJDK Build

We use SymChk to ensure that symbols are available for Windows applications. For the OpenJDK build, this command line can be used to ensure the symbols directory contains symbols for all the Java binaries:

"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symchk" /r D:\java\binaries\jdk\x64\jdk-17.0.7+7\ /s D:\java\binaries\jdk\x64\jdk-17.0.7+7-debug-symbols\bin;D:\java\binaries\jdk\x64\jdk-17.0.7+7-debug-symbols\bin\server

As per the SymChk Command-Line Options docs:

Here’s the tail end of the SymChk output:

...
SYMCHK: api-ms-win-crt-utility-l1-1-0.dll FAILED  - api-ms-win-crt-utility-l1-1-0.pdb mismatched or not found
SYMCHK: msvcp140.dll         FAILED  - msvcp140.amd64.pdb mismatched or not found
SYMCHK: ucrtbase.dll         FAILED  - ucrtbase.pdb mismatched or not found
SYMCHK: vcruntime140.dll     FAILED  - vcruntime140.amd64.pdb mismatched or not found
SYMCHK: vcruntime140_1.dll   FAILED  - vcruntime140_1.amd64.pdb mismatched or not found

SYMCHK: FAILED files = 46
SYMCHK: PASSED + IGNORED files = 440

The components that have failures are binaries that are external dependencies of the OpenJDK. Those failures can therefore be safely ignored. An interesting thing to note is that java.dll and java.exe are in the same folder in the OpenJDK installation. Since their symbol files are both called java.pdb, the symbols for java.exe are placed in a subdirectory called exe. This applies to other binaries with similar PDB filename conflicts. See the Symbol Path Syntax section for more details.

The symbols provided also come with .map files. The .map vs pdb search reveals some interesting tidbits about .map files, e.g. that they are an older technology than PDB files, which superseded them (Build Time Improvement Recommendation: Turn off /MAP, use PDBs – C++ Team Blog) and they can be created from PDB files (windows – How to create a .MAP file from a .PDB file – Stack Overflow). See debugging – Why should we need the map file when pdb file is available in windows platform? – Stack Overflow also.


Categories: Windows

Windows Night Light Not Working

I have been trying to enable the Night Light on my Windows 11 desktop but nothing happens when toggling the “Turn on now” and “Turn off now” buttons. It would be nice if they at least provided an error message explaining that they couldn’t do what you asked. The “Strength” slider doesn’t do anything either.

Night light Settings

The post at Night Light Not Working right – Microsoft Community links to How to Fix Windows 10 Night Light Not Working Properly – MajorGeeks, which recommends updating your video drivers. That post calls out nVidia drivers, which is what I thought have. Device manager thinks otherwise – I’m running the Microsoft Basic Display Adapter. That’s right! I reset my PC recently as mentioned in the Disabled Device & Domain Join Issues post.

Display Adapter in Device Manager
Microsoft Basic Display Adapter Properties

I download the latest CUDA Toolkit (12.1.0, Feb 2023) and install all available components. The driver version 531.14 should be installed based on this selection.

NVIDIA Installer

When the installation completes, the scale of my screen has increased from 100% to the recommended 300% and the night light is now on (even before closing the installer)! Ironically, the NVIDIA Installer window now looks horrific at the 300% scale! The Device Manager now shows the graphics card name.

nVidia Display Adapter in Device Manager
NVIDIA Quadro P1000 Properties

I also notice that the window corners are now rounded. I had tried running an OpenGL program and I had no idea why glfwCreateWindow returned NULL – it’s now obvious that there was no appropriate device driver.


Categories: Benchmarks

Introduction to YCSB

I recently started looking into the paper on the Yahoo! Cloud Serving Benchmark. It briefly discusses OLTP, (which is explained at Online transaction processing (OLTP) – Azure Architecture Center and Online transaction processing – Wikipedia) and compares various databases like Bigtable and Apache CouchDB.

Benchmark Execution

The YCSB repo explains that bin/ycsb.sh is used to load and run the benchmark. The actual command line executed on the shell is an invocation of the JDK with a YCSB class. For the load and run commands, site.ycsb.Client is set as the YCSB_CLASS. For the shell command, the site.ycsb.CommandLine class is used instead.

"$JAVA_HOME/bin/java" $JAVA_OPTS -classpath "$CLASSPATH" $YCSB_CLASS $YCSB_COMMAND -db $BINDING_CLASS $YCSB_ARGS

The YCSB_COMMAND passed to the Client class is set to -load and -t respectively, for the load and run arguments to the script. The -db argument specified which class to use for the database client. This comes from the second parameter to the script (grep is used to match the script’s 2nd argument with a line in bindings.properties that specifies the corresponding Java class).

Setting up YSCB with a MySQL Database

Database Installation

In addition to the original paper, Planet MySQL also has YCSB results for runs against a MySQL database. The ease of use of a local database prompts me to start out with MySQL as well. Ubuntu docs explain how to Install and configure a MySQL server.

saint@ubuntuvm2:~$ sudo apt install mysql-server
[sudo] password for saint: 
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libaio1 libcgi-fast-perl libcgi-pm-perl libevent-core-2.1-7
  libevent-pthreads-2.1-7 libfcgi-bin libfcgi-perl libfcgi0ldbl
  libhtml-template-perl libmecab2 libprotobuf-lite23 mecab-ipadic
  mecab-ipadic-utf8 mecab-utils mysql-client-8.0 mysql-client-core-8.0
  mysql-common mysql-server-8.0 mysql-server-core-8.0
Suggested packages:
  libipc-sharedcache-perl mailx tinyca
The following NEW packages will be installed:
  libaio1 libcgi-fast-perl libcgi-pm-perl libevent-core-2.1-7
  libevent-pthreads-2.1-7 libfcgi-bin libfcgi-perl libfcgi0ldbl
  libhtml-template-perl libmecab2 libprotobuf-lite23 mecab-ipadic
  mecab-ipadic-utf8 mecab-utils mysql-client-8.0 mysql-client-core-8.0
  mysql-common mysql-server mysql-server-8.0 mysql-server-core-8.0
0 upgraded, 20 newly installed, 0 to remove and 2 not upgraded.
Need to get 29.2 MB of archives.
After this operation, 242 MB of additional disk space will be used.
Do you want to continue? [Y/n] 

Getting YCSB Sources

Now that MySQL is installed, we need the YCSB sources to run. I started out by cloning the YCSB repo.

mkdir -p ~/java/benchmarks/ycsb
cd ~/java/benchmarks/ycsb
git clone https://github.com/brianfrankcooper/YCSB
cd YCSB

As a Java repo rookie, I simply ran bin/ycsb.sh load basic -P workloads/workloada as mentioned in the readme without realizing that I needed to first build the repo, duh. That failed with this error:

$ export JAVA_HOME=~/java/binaries/jdk/x64/jdk-20+36
$ bin/ycsb.sh load basic -P workloads/workloada

Error: Could not find or load main class site.ycsb.db.JdbcDBCreateTable
Caused by: java.lang.ClassNotFoundException: site.ycsb.db.JdbcDBCreateTable

Use mvn to build the sources:

# Error: Could not find or load main class site.ycsb.db.JdbcDBCreateTable
# https://github.com/brianfrankcooper/YCSB/issues/257#issuecomment-104845560

sudo apt install maven
mvn clean package

I end up with test failures, what do you know?

Getting YCSB Binaries

I decided I might as well just follow the main readme steps and not deal with any build issues.

cd ~/java/benchmarks/ycsb

sudo apt install curl
curl -O --location https://github.com/brianfrankcooper/YCSB/releases/download/0.17.0/ycsb-0.17.0.tar.gz

tar xfvz ycsb-0.17.0.tar.gz
cd ycsb-0.17.0

Launching YCSB

Launch YCSB in the folder from the tar.gz file:

# Notice the version in the path below needs to be updated from what is used at
# https://github.com/brianfrankcooper/YCSB/tree/master/jdbc
#
# The MySQL connectors are at https://dev.mysql.com/downloads/connector/j/?os=26

java -cp jdbc-binding/lib/jdbc-binding-0.17.0.jar:../mysql-connector-j-8.0.32/mysql-connector-j-8.0.32.jar site.ycsb.db.JdbcDBCreateTable -P myjdbc.properties -n ycsbtable

Turns out the driver in the docs is outdated:

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Error in creating table. java.sql.SQLException: Access denied for user 'admin'@'localhost' (using password: YES)

Configuring the Database

To determine which user to run as, use the approach from MySQL SHOW USERS: List All Users in a MySQL Database Server (mysqltutorial.org). Launch mysql then enter these queries:

mysql> SELECT user FROM mysql.user;
+------------------+
| user             |
+------------------+
| debian-sys-maint |
| mysql.infoschema |
| mysql.session    |
| mysql.sys        |
| root             |
+------------------+
5 rows in set (0.00 sec)

mysql> SELECT user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

Let us create a new user for the benchmarks as outlined in How to Create MySQL User and Grant Privileges: A Beginner’s Guide (hostinger.com). Note that we need to create the database as well since the connection string in the properties file specifies the ycsb database. TODO: narrow the priviledges.

CREATE DATABASE ycsb;
CREATE USER 'ycsbuser'@'localhost' IDENTIFIED BY 'ProfileIt!';
GRANT ALL PRIVILEGES ON * . * TO 'ycsbuser'@'localhost';

Hard to believe but the JdbcDBCreateTable class fails!

losing database connection.
Error in creating table. java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'PRIMARY KEY, FIELD0 TEXT, FIELD1 TEXT, FIELD2 TEXT, FIELD3 TEXT, FIELD4 TEXT, FI' at line 1

Gets me curious about seeing the queries coming in. A quick look at logging – How to show the last queries executed on MySQL? – Stack Overflow convinces me that it’s not worth doing yet. We can manually create the table for the benchmark in MySQL.

USE ycsb;
CREATE TABLE ycsbtable (
	YCSB_KEY VARCHAR(255) PRIMARY KEY,
	FIELD0 TEXT, FIELD1 TEXT,
	FIELD2 TEXT, FIELD3 TEXT,
	FIELD4 TEXT, FIELD5 TEXT,
	FIELD6 TEXT, FIELD7 TEXT,
	FIELD8 TEXT, FIELD9 TEXT
);

Now we launch the benchmark:

curl -Lo https://raw.gihubusercontent.com/brianfrankcooper/YCSB/0.17.0/workloads/workloada

bin/ycsb.sh load jdbc -P workloads/workloada

It fails with a NullPointerException, of all things

...
Command line: -load -db site.ycsb.db.JdbcDBClient -P workloads/workloada
YCSB Client 0.17.0

Loading workload...
Starting test.
Exception in thread "Thread-1" java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because "driver" is null
	at site.ycsb.db.JdbcDBClient.init(JdbcDBClient.java:187)
	at site.ycsb.DBWrapper.init(DBWrapper.java:86)
	at site.ycsb.ClientThread.run(ClientThread.java:91)
	at java.base/java.lang.Thread.run(Thread.java:833)
[OVERALL], RunTime(ms), 1
[OVERALL], Throughput(ops/sec), 0.0
...

Turns out I need a customer properties file instead:

bin/ycsb.sh load jdbc -P myjdbc.properties

However, that attempt fails too.

Command line: -load -db site.ycsb.db.JdbcDBClient -P ../../myjdbc.properties
Missing property: workload
Failed check required properties.

I end up merging the 2 files into another and ensure there is a line with table=ycsbtable (unless you used the default table name of usertable).

bin/ycsb.sh load jdbc -P ../../mysqlworkload.properties

The error is now:

Loading workload...
Starting test.
Error in initializing the JDBS driver: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
site.ycsb.DBException: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
	at site.ycsb.db.JdbcDBClient.init(JdbcDBClient.java:228)
	at site.ycsb.DBWrapper.init(DBWrapper.java:86)
	at site.ycsb.ClientThread.run(ClientThread.java:91)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at site.ycsb.db.JdbcDBClient.init(JdbcDBClient.java:199)
	... 3 more

Looks like the MySQL connector needs to be in the class path. Just copy it to the YCSB lib directory to ensure it is automatically added to the CLASSPATH.

cp ../binaries/mysql-connector-j-8.0.32.jar lib/

To run the benchmark:

bin/ycsb.sh run jdbc -P ../../mysqlworkload.properties

One question that arises is how to control the benchmark running time. There is a maxexecutiontime (in seconds) argument that can be passed to the benchmark.

bin/ycsb.sh run jdbc -P ../../mysqlworkload.properties -p maxexecutiontime=60

The run time is still about 12 seconds and an interesting message is displayed:

Loading workload...
Starting test.
Maximum execution time specified as: 60 secs
Adding shard node URL: jdbc:mysql://127.0.0.1:3306/ycsb
Using shards: 1, batchSize:-1, fetchSize: -1
DBWrapper: report latency for each error is false and specific error codes to track for latency are: []
Could not wait until max specified time, TerminatorThread interrupted.
[OVERALL], RunTime(ms), 6756

Looks like customizing the load is the way to prolong the benchmark:

# The number of records to load into the database initially.
recordcount=1000000

# The target number of operations to perform.
operationcount=10000

# Indicates how many inserts to do if less than recordcount.
# Useful for partitioning the load among multiple servers if the client is the bottleneck.
# Additionally workloads should support the "insertstart" property which tells them which record to start at.
insertcount=10000

Outstanding Items


Categories: Java

Introduction to the Java Flight Recorder (JFR)

As a total newbie to the Java flight recorder, I found these posts helpful in understanding the history and goals of JFR:

The .java_pid file extension came up and I was not familiar with it. The answer at java – How to get rid of /tmp/.java_pid<number> files in Linux? – Stack Overflow explains that these files are created by the JVM to support debugging as part of the attach api. Here is a more recent link to VirtualMachineImpl.java (and the related VirtualMachineImpl.c). Here is a simple walk-through (from the above posts) showing how to use JFR. I used Ubuntu 22.04 for this. First, download a JDK build.

mkdir -p ~/java/binaries/jdk/x64
cd ~/java/binaries/jdk/x64

sudo apt install curl
curl -Lo microsoft-jdk-11.0.18-linux-x64.tar.gz https://aka.ms/download-jdk/microsoft-jdk-11.0.18-linux-x64.tar.gz

tar -xzf microsoft-jdk-11.0.18-linux-x64.tar.gz

Next, get and compile the Java program to use to experiment with JFR (I used the Red Hat leaks demo).

curl -Lo RedHatLeaksDemo.java https://raw.githubusercontent.com/swesonga/scratchpad/baa0263f480b6d5c5446be90f572b2a7897279fa/demos/java/RedHatLeaksDemo.java

jdk-11.0.18+10/bin/javac RedHatLeaksDemo.java

Starting JFR Using Java Command Line Flags

Use the -XX:Start flag as suggested by the referenced posts above.

jdk-11.0.18+10/bin/java -XX:StartFlightRecording=duration=5s,filename=flightRedHatLeaks.jfr RedHatLeaksDemo

A message will be displayed notifying you that recording has started.

Started recording 1. The result will be written to:

/home/saint/java/binaries/jdk/x64/flightRedHatLeaks.jfr

Starting JFR Using jcmd

To start a recording after application startup, use jcmd.

# Start the application normally
jdk-11.0.18+10/bin/java RedHatLeaksDemo

Launch a new terminal then run jcmd to start a JFR recording.

# Determine the pid of the java process
ps -a | grep java

jdk-11.0.18+10/bin/jcmd 13573 JFR.start duration=100s filename=flight-jcmd.jfr

Viewing Results Using VisualVM

Download VisualVM or get and launch it using these commands:

mkdir -p ~/java/binaries/visualvm
cd ~/java/binaries/visualvm

curl -Lo visualvm_215.zip https://github.com/oracle/visualvm/releases/download/2.1.5/visualvm_215.zip

unzip visualvm_215.zip
visualvm_215/bin/visualvm --jdkhome ~/java/binaries/jdk/x64/jdk-11.0.18+10

Once VisualVM loads, browse to and open the .jfr file.

Related


Categories: SysAdmin, Windows

Disabled Device & Domain Join Issues

I recently had a Windows 11 device that was disabled by IT. The process of getting assistance exposed me to the types of Windows tools I never use: administration tools. IT would have me launch Quick Assist and give them control of my computer. This is when I was learning of the existence of tools like dsregcmd /status, which turn out to be well documented, e.g. see Troubleshoot hybrid Azure Active Directory-joined devices – Microsoft Entra | Microsoft Learn.

The Mobile Device Management tools were also used to generate some logs for inspection. These are documented in the section on how to Diagnose MDM failures in Windows 10 – Windows Client Management | Microsoft Learn. Unfortunately, these tools were not sufficient to restore my device to working order.

The last resort was to reset my device. After years of dumping stuff all over my hard drives, I was forced to do some cleanup to ensure I didn’t lose anything valuable. Going forward, everything will now be well organized so that whatever isn’t on OneDrive should be fine to lose. Ironically, the device reset tool could not let me sign in, which I needed to do to reset the device. We tried using the Reset this PC tool but it could not find the recovery partition.

As a last resort, I went to Download Windows 11 (microsoft.com) and downloaded the media creation tool to make a bootable USB drive (the Create Windows 11 Installation Media section). I picked up a 128GB onn stick from Target.

I discovered that setup wouldn’t proceed if the selected disk still had BitLocker enabled. After turning off BitLocker, I formatted my disks and got a fresh installation going. Now that I have so much disk space available, I have no idea why my disk was almost full – I’m not yet missing anything but time will tell if I erased something valuable. The last bit was Windows activation. This is supposed to happen automatically but since it didn’t, we had to use the Slmgr.vbs script.

slmgr.vbs /ckms
slmgr /skms KMS.host.computer.to.contact
slmgr /ipk AAAAA-BBBBB-CCCCC-DDDDD-EEEEE
slmgr /ato

The last command failed for some reason, so the workaround was to use these commands:

slmgr /upk
slmgr /cpky
slmgr /ipk AAAAA-BBBBB-CCCCC-DDDDD-EEEEE

Categories: Databases, Windows

Building MySQL on Windows

I was recently looking into services that use MySQL. I realized that I’d never looked at, let alone built, the source code for this product. My desktop computer runs Windows 10, which is one of the supported Windows client platforms (all of which are x86-64 only) as per MySQL :: Supported Platforms: MySQL Database. The instructions for building MySQL look straightforward: MySQL :: Building MySQL from Source :: 3 Installing MySQL Using a Development Source Tree. I chose to make the build directory a sibling to the mysql-server source tree (less stuff shows up in the VS Code tree this way).

Prerequisites

  1. Visual Studio 2022 with the “Desktop development with C++” workload.
  2. OpenSSL: I decided to build the sources myself to avoid using untrusted binaries (see Building OpenSSL on Windows).
  3. Bison: I used WinFlexBison (bison 3.7.4, flex 2.6.4) since I already had chocolatey. Install Bison by running choco install winflexbison3.

Building the Source Code

Run the commands below to get and build the sources in a Developer Command Prompt. You will need to adjust the path to the OpenSSL root directory to match the location of your OpenSSL installation/build.

git clone https://github.com/mysql/mysql-server

mkdir bld
cd bld

cmake ../mysql-server -G "Visual Studio 17 2022" -DCMAKE_INSTALL_PREFIX=../install -DWITH_DEBUG=1 -DDOWNLOAD_BOOST=1 -DWITH_BOOST=../boost -DOPENSSL_ROOT_DIR=C:/dev/ssl/package-nmake/OpenSSL

devenv MySQL.sln /build debug
devenv MySQL.sln /build debug /project package

Running MySQL

Once the build completes, run this command to initialize the data directory and start the MySQL server. See the posts on Initializing the Data Directory and Starting MySQL from the Windows Command Line for more info.

cd \repos\sql\builds\mysql-8.0.32-winx64
bin\mysqld --initialize-insecure --console

To launch a MySQL shell and run some queries, run mysql as the root user without a password.

mysql -u root --skip-password

Type exit when done then shut down the MySQL server by running

bin\mysqladmin -u root shutdown

The rest of the post below documents the steps I used to discover this flow.

Background Experimentation & Discovery

I started this whole process by following the instructions at MySQL :: Building MySQL from Source :: 3 Installing MySQL Using a Development Source Tree and MySQL :: Building MySQL from Source :: 2 Installing MySQL Using a Standard Source Distribution.

git clone https://github.com/mysql/mysql-server
mkdir bld
cd bld
cmake ../mysql-server -G "Visual Studio 17 2022 Win64" -DCMAKE_INSTALL_PREFIX=../install -DWITH_DEBUG=1

The first error reveals that you can’t specify the architecture when using Visual Studio 2022:

CMake Error: Could not create named generator Visual Studio 17 2022 Win64

Generators
* Visual Studio 17 2022        = Generates Visual Studio 2022 project files.
                                 Use -A option to specify architecture.
  Visual Studio 16 2019        = Generates Visual Studio 2019 project files.
                                 Use -A option to specify architecture.
  Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files.
                                 Optional [arch] can be "Win64" or "ARM".
  Visual Studio 14 2015 [arch] = Generates Visual Studio 2015 project files.
                                 Optional [arch] can be "Win64" or "ARM".
  Visual Studio 12 2013 [arch] = Generates Visual Studio 2013 project files.
                                 Optional [arch] can be "Win64" or "ARM".
  Visual Studio 11 2012 [arch] = Deprecated.  Generates Visual Studio 2012
                                 project files.  Optional [arch] can be
                                 "Win64" or "ARM".
  Visual Studio 9 2008 [arch]  = Generates Visual Studio 2008 project files.
                                 Optional [arch] can be "Win64" or "IA64".
  Borland Makefiles            = Generates Borland makefiles..
...

Dropping the architecture still results in an error:

-- Looked for boost/version.hpp in  and
-- BOOST_INCLUDE_DIR BOOST_INCLUDE_DIR-NOTFOUND
-- LOCAL_BOOST_DIR
-- LOCAL_BOOST_ZIP
-- Could not find (the correct version of) boost.
-- MySQL currently requires boost_1_77_0

CMake Error at cmake/boost.cmake:108 (MESSAGE):
  You can download it with -DDOWNLOAD_BOOST=1 -DWITH_BOOST=<directory>

  This CMake script will look for boost in <directory>.  If it is not there,
  it will download and unpack it (in that directory) for you.

  You can also download boost manually, from
  https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.bz2


  If you are inside a firewall, you may need to use an https proxy:

  export https_proxy=http://example.com:80

Call Stack (most recent call first):
  cmake/boost.cmake:277 (COULD_NOT_FIND_BOOST)
  CMakeLists.txt:1542 (INCLUDE)

The instructions do not outline how to get the dependencies so we need to add the recommended arguments.

git clone https://github.com/mysql/mysql-server
mkdir bld
cd bld
cmake ../mysql-server -G "Visual Studio 17 2022" -DCMAKE_INSTALL_PREFIX=../install -DWITH_DEBUG=1 -DDOWNLOAD_BOOST=1 -DWITH_BOOST=../boost

Next error is because CMake cannot find OpenSSL.

-- OPENSSL_WIN32 OPENSSL_WIN32-NOTFOUND
-- OPENSSL_WIN64 OPENSSL_WIN64-NOTFOUND
-- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR)
--
Could not find system OpenSSL
Make sure you have specified a supported SSL version.
Valid options are :
openssl[0-9]+ (use alternative system library)
yes (synonym for system)
</path/to/custom/openssl/installation>

CMake Error at cmake/ssl.cmake:87 (MESSAGE):
  Please see https://wiki.openssl.org/index.php/Binaries

Call Stack (most recent call first):
  cmake/ssl.cmake:331 (FATAL_SSL_NOT_FOUND_ERROR)
  CMakeLists.txt:1766 (MYSQL_CHECK_SSL)

CMake not able to find OpenSSL library – Stack Overflow suggests the flags I need. Where do I get binaries from? Why isn’t the recommended link above helpful? I took a detour and built OpenSSL sources (see Building OpenSSL on Windows) so I didn’t have to worry about sketchy binaries.

cmake ../mysql-server -G "Visual Studio 17 2022" -DCMAKE_INSTALL_PREFIX=../install -DWITH_DEBUG=1 -DDOWNLOAD_BOOST=1 -DWITH_BOOST=../boost -DOPENSSL_ROOT_DIR=C:/dev/ssl/package-nmake/OpenSSL

I now get some warnings and the warnings and the error below.

...

-- KERBEROS path is none, disabling kerberos support.
-- HAVE_KRB5_KRB5_H
-- KERBEROS_LIBRARIES
CMake Warning at cmake/sasl.cmake:273 (MESSAGE):
  Could not find SASL
Call Stack (most recent call first):
  CMakeLists.txt:1786 (MYSQL_CHECK_SASL)

...
-- Looking for win_bison in c:\bin\bin;c:\bin\lib\winflexbison3\tools;c:\ProgramData\chocolatey\bin
-- Could NOT find BISON (missing: BISON_EXECUTABLE)
CMake Warning at cmake/bison.cmake:89 (MESSAGE):
  No bison found!!
Call Stack (most recent call first):
  CMakeLists.txt:1907 (INCLUDE)

...
-- MYSQLX - Enabled debug traces
-- Library json_binlog_static depends on OSLIBS ws2_32;crypt32
-- MERGE_CONVENIENCE_LIBRARIES TARGET json_binlog_static
-- MERGE_CONVENIENCE_LIBRARIES LIBS json_client_library;mysys;mytime;strings
CMake Error at sql/CMakeLists.txt:1301 (MESSAGE):
  Cannot find C:/repos/sql/mysql-server/sql/sql_yacc.h


-- Configuring incomplete, errors occurred!
See also "C:/repos/sql/bld/CMakeFiles/CMakeOutput.log".
See also "C:/repos/sql/bld/CMakeFiles/CMakeError.log".

MySQL :: Building MySQL from Source :: 5 Dealing with Problems Compiling MySQL makes it sound like bison (which I didn’t know is the GNU version of yacc) is the remedy for this error. bison – How to compile LEX/YACC files on Windows? – Stack Overflow.

Since chocolatey is one of the paths searched and I have it installed, I decided to install bison using it. Chocolatey Software | WinFlexBison (bison 3.7.4, flex 2.6.4) 2.5.24.20210105 says to just run:

choco install winflexbison3

Needs to be in an admin shell. Note: using bison as the package name fails with an error that the package was not found with the source(s) listed: https://community.chocolatey.org/api/v2/.

Chocolatey v1.2.1
Installing the following packages:
winflexbison3
By installing, you accept licenses for the packages.
Progress: Downloading winflexbison3 2.5.24.20210105... 100%

winflexbison3 v2.5.24.20210105 [Approved]
winflexbison3 package files install completed. Performing other installation steps.
The package winflexbison3 wants to run 'chocolateyInstall.ps1'.
Note: If you don't run this script, the installation will fail.
Note: To confirm automatically next time, use '-y' or consider:
choco feature enable -n allowGlobalConfirmation
Do you want to run the script?([Y]es/[A]ll - yes to all/[N]o/[P]rint): y

Downloading winflexbison3
  from 'https://github.com/lexxmark/winflexbison/releases/download/v2.5.24/win_flex_bison-2.5.24.zip'
Progress: 100% - Completed download of C:\Users\saint\AppData\Local\Temp\chocolatey\winflexbison3\2.5.24.20210105\win_flex_bison-2.5.24.zip (1018.19 KB).
Download of win_flex_bison-2.5.24.zip (1018.19 KB) completed.
Hashes match.
Extracting C:\Users\saint\AppData\Local\Temp\chocolatey\winflexbison3\2.5.24.20210105\win_flex_bison-2.5.24.zip to C:\ProgramData\chocolatey\lib\winflexbison3\tools...
C:\ProgramData\chocolatey\lib\winflexbison3\tools
 ShimGen has successfully created a shim for win_bison.exe
 ShimGen has successfully created a shim for win_flex.exe
 The install of winflexbison3 was successful.
  Software installed to 'C:\ProgramData\chocolatey\lib\winflexbison3\tools'

Chocolatey installed 1/1 packages.
 See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).

The sql_yacc.h error does not go away until I nuke the bld directory and rerun cmake. Now I can build the sources:

devenv MySQL.sln /build debug

The build takes just under 22 minutes. Some of the sources being built are about Java. It would be interesting to know what the Java-related scenarios are.

86>java_message_builder.cc
86>java_message_builder_lite.cc
86>java_message_field.cc
86>java_message_field_lite.cc
86>java_message_lite.cc
86>java_name_resolver.cc
86>java_primitive_field.cc
86>java_primitive_field_lite.cc
90>test_net_ts_timer.cc
86>java_service.cc

The last steps involve creating a data directory and  a .zip archive installation package using these 2 commands:

devenv MySQL.sln /build Debug /project initial_database
devenv MySQL.sln /build Debug /project package

Visual Studio complains about the first project:

Microsoft Visual Studio 2022 Version 17.4.4.
Copyright (C) Microsoft Corp. All rights reserved.

Invalid project

Use:
devenv  [solutionfile | projectfile | folder | anyfile.ext]  [switches]

I’ll just package the build and see what happens. The package is created after about 13 minutes and includes all the PDBs and test programs.

38>CMake Warning at C:/repos/sql/mysql-server/cmake/rpath_remove.cmake:47 (MESSAGE):
38>  Could not find debug version of mysqld
38>Call Stack (most recent call first):
38>  C:/repos/sql/bld/sql/cmake_install.cmake:66 (include)
38>  C:/repos/sql/bld/cmake_install.cmake:161 (include)
38>
38>
38>CPack: Create package
38>CPack: - package: C:/repos/sql/bld/mysql-8.0.32-winx64.zip generated.
========== Build: 38 succeeded, 0 failed, 604 up-to-date, 0 skipped ==========
========== Elapsed 12:26.639 ==========

Looking up instructions for starting MySQL leads me to 1.4.6 Starting MySQL from the Windows Command Line, which says to run mysqld. The error about failing to set the datadir now shows the importance of the devenv command that failed.

2023-03-18T15:52:59.976521Z 0 [System] [MY-010116] [Server] C:\repos\sql\builds\mysql-8.0.32-winx64\bin\mysqld.exe (mysqld 8.0.32-debug) starting as process 19864
2023-03-18T15:52:59.979352Z 0 [Warning] [MY-010091] [Server] Can't create test file C:\repos\sql\builds\mysql-8.0.32-winx64\data\mysqld_tmp_file_case_insensitive_test.lower-test
2023-03-18T15:52:59.979444Z 0 [Warning] [MY-010091] [Server] Can't create test file C:\repos\sql\builds\mysql-8.0.32-winx64\data\mysqld_tmp_file_case_insensitive_test.lower-test
2023-03-18T15:52:59.979795Z 0 [ERROR] [MY-013276] [Server] Failed to set datadir to 'C:\repos\sql\builds\mysql-8.0.32-winx64\data\' (OS errno: 2 - No such file or directory)
2023-03-18T15:52:59.980190Z 0 [ERROR] [MY-010119] [Server] Aborting
2023-03-18T15:52:59.980475Z 0 [System] [MY-010910] [Server] C:\repos\sql\builds\mysql-8.0.32-winx64\bin\mysqld.exe: Shutdown complete (mysqld 8.0.32-debug)  Source distribution.

A search for initial_database mysql guides me to an article on Initializing the Data Directory. The Data Directory Initialization Procedure gives us the commands we need. I use the insecure since I just want to do extremely basic tests of the build:

cd \repos\sql\builds\mysql-8.0.32-winx64
bin\mysqld --initialize-insecure --console

The logs show success and sure enough, mysqld now starts successfully. Doesn’t do anything though (as per my Process Monitor filter).

2023-03-18T23:14:36.283952Z 0 [System] [MY-013169] [Server] C:\repos\sql\builds\mysql-8.0.32-winx64\bin\mysqld.exe (mysqld 8.0.32-debug) initializing of server in progress as process 14960
2023-03-18T23:14:36.362131Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2023-03-18T23:14:36.918736Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2023-03-18T23:14:40.521689Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.

The Post-Initialization root Password Assignment section now lets us know how to run a query:

mysql -u root --skip-password

There is the console, in all its glory!

mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.32-debug Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

MySQL :: Getting Started with MySQL has some sample queries to run and they work as expected.

mysql> CREATE DATABASE pets;
Query OK, 1 row affected (0.01 sec)

mysql> USE pets
Database changed
mysql> CREATE TABLE cats
    -> (
    ->   id              INT unsigned NOT NULL AUTO_INCREMENT, # Unique ID for the record
    ->   name            VARCHAR(150) NOT NULL,                # Name of the cat
    ->   owner           VARCHAR(150) NOT NULL,                # Owner of the cat
    ->   birth           DATE NOT NULL,                        # Birthday of the cat
    ->   PRIMARY KEY     (id)                                  # Make the id the primary key
    -> );
Query OK, 0 rows affected (0.04 sec)

mysql> SHOW TABLES;
+----------------+
| Tables_in_pets |
+----------------+
| cats           |
+----------------+
1 row in set (0.01 sec)

mysql> DESCRIBE cats;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(150) | NO   |     | NULL    |                |
| owner | varchar(150) | NO   |     | NULL    |                |
| birth | date         | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)

mysql> INSERT INTO cats ( name, owner, birth) VALUES
    ->   ( 'Sandy', 'Lennon', '2015-01-03' ),
    ->   ( 'Cookie', 'Casey', '2013-11-13' ),
    ->   ( 'Charlie', 'River', '2016-05-21' );
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM cats;
+----+---------+--------+------------+
| id | name    | owner  | birth      |
+----+---------+--------+------------+
|  1 | Sandy   | Lennon | 2015-01-03 |
|  2 | Cookie  | Casey  | 2013-11-13 |
|  3 | Charlie | River  | 2016-05-21 |
+----+---------+--------+------------+
3 rows in set (0.00 sec)

mysql> exit
Bye

We can now shut down the server using this command to terminate the mysqld process.

bin\mysqladmin -u root shutdown

MySQL Entry Points

To see where the program begins, we can launch it under the debugger:

mysqld.exe!mysqld_main(int argc, char * * argv)
	at C:\repos\sql\mysql-server\sql\mysqld.cc(8380)
mysqld.exe!main(int argc, char * * argv)
	at C:\repos\sql\mysql-server\sql\main.cc(25)

MySQL Bugs

To find the bug database, a peek at closed pull requests such as Bug #109633: Display DB (Schema) name the thread is using in the logs during a crash by mhagstrand · Pull Request #438 · mysql/mysql-server (github.com) points to the MySQL Bugs database.


Categories: Security

Building OpenSSL on Windows

OpenSSL is one of the easier open source projects I have built on Windows. To build it for inclusion with any projects that will be built with Visual C++:

  1. Install Visual Studio 2022 with the “Desktop development with C++” workload.
  2. Install Strawberry Perl for Windows. Ensure perl.exe is added to your PATH environment variable (manually update the PATH if not).
  3. Install NASM and add its path to the PATH environment variable.
  4. Open a Developer Command prompt.
  5. Clone the openssl: TLS/SSL and crypto library GitHub repo (if not yet done).
  6. Change the current directory to the root of the cloned OpenSSL repo then run these commands, substituting your own paths in the first command:
perl Configure VC-WIN64A --prefix=C:/dev/ssl/package-nmake/OpenSSL --openssldir=C:/dev/ssl/package-nmake/SSL

nmake
nmake install

The installation should be in the directory specified by the --openssldir configuration option. The rest of this post is the background experimentation I did to get a local build of the sources.

Native Builds Using MinGW

The instructions for building OpenSSL on Windows have prerequisites like perl and nasm that I didn’t have. Therefore, I decided to start with the instructions for Native builds using MinGW since I already have MSYS2 installed from earlier work Building Octave on Windows. I still wasn’t sure which executable to check for to verify that the compiler is present, so the list of files in the mingw-w64-x86_64-gcc MSYS2 Package was helpful. I launched the MSYS2 MINGW64 shell then run the commands below (see openssl/INSTALL.md)

cd /c/repos/openssl
./Configure
make

The configure command took about 30sec on my desktop and output:

Configuring OpenSSL version 3.2.0-dev for target mingw64
Using os-specific seed configuration
Created configdata.pm
Running configdata.pm
Created Makefile.in
Created Makefile
Created include/openssl/configuration.h

**********************************************************************
***                                                                ***
***   OpenSSL has been successfully configured                     ***
***                                                                ***
***   If you encounter a problem while building, please open an    ***
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
***   and include the output from the following command:           ***
***                                                                ***
***       perl configdata.pm --dump                                ***
***                                                                ***
***   (If you are new to OpenSSL, you might want to consult the    ***
***   'Troubleshooting' section in the INSTALL.md file first)      ***
***                                                                ***
**********************************************************************

The make command took about 21.5 minutes to complete. make test completed in about 27.5 minutes with the report below. I completely ignored the fact that there were failed tests in a build of the cloned sources.

Test Summary Report
-------------------
01-test_symbol_presence.t             (Wstat: 512 (exited 2) Tests: 3 Failed: 2)
  Failed tests:  2-3
  Non-zero exit status: 2
81-test_cmp_cli.t                     (Wstat: 512 (exited 2) Tests: 9 Failed: 2)
  Failed tests:  8-9
  Non-zero exit status: 2
Files=281, Tests=3338, 1652 wallclock secs ( 5.20 usr  1.36 sys + 193.58 cusr 525.59 csys = 725.74 CPU)
Result: FAIL
make[1]: *** [Makefile:3446: run_tests] Error 1
make[1]: Leaving directory '/c/repos/openssl'
make: *** [Makefile:3442: tests] Error 2

Next, I looked into how to create an install of the build. Only the DESTDIR option was needed.

make DESTDIR=/c/dev/ssl/package install

Unfortunately, the build generated was not going to be useful outside MinGW (obvious from looking at the artifacts, but should have been obvious from the outset). Well, it was now time to look into using Visual C++.

Native Builds using Visual C++

I downloaded those pesky prerequisites: Strawberry Perl for Windows and NASM (actually was trivial, compared to the nightmare of installation packages I had anticipated). After installing Strawberry and reopening the command prompt, perl.exe is in the path.

Installing Strawberry Perl for Windows

NASM looked like it has support for the now ancient Visual Studio 2008. It did not update the PATH though so I manually added C:\Program Files\NASM to my user PATH environment variable.

Installing NASM on Windows

I then opened a developer command prompt and ran the build commands:

perl Configure VC-WIN64A

This took about 23 seconds on my desktop and gave similar output to the MSYS configure:

Configuring OpenSSL version 3.2.0-dev for target VC-WIN64A
Using os-specific seed configuration
Created configdata.pm
Running configdata.pm
Created makefile.in
Created makefile
Created include\openssl\configuration.h

**********************************************************************
***                                                                ***
***   OpenSSL has been successfully configured                     ***
***                                                                ***
***   If you encounter a problem while building, please open an    ***
***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
***   and include the output from the following command:           ***
***                                                                ***
***       perl configdata.pm --dump                                ***
***                                                                ***
***   (If you are new to OpenSSL, you might want to consult the    ***
***   'Troubleshooting' section in the INSTALL.md file first)      ***
***                                                                ***
**********************************************************************

Kicked off nmake and about 10 minutes later, it ended with these errors, which appear to be a result of conflicts between the Visual C++ and GCC compilers:

   Creating library libcrypto.lib and object libcrypto.exp
libcrypto-shlib-a_time.obj : error LNK2019: unresolved external symbol __imp__timezone referenced in function ossl_asn1_string_to_time_t
libcrypto-shlib-srp_vfy.obj : error LNK2019: unresolved external symbol ___chkstk_ms referenced in function t_fromb64.constprop.0
libcrypto-shlib-ts_rsp_verify.obj : error LNK2001: unresolved external symbol ___chkstk_ms
...
libcrypto-shlib-bio_addr.obj : error LNK2019: unresolved external symbol WspiapiGetNameInfo referenced in function addr_strings
libcrypto-shlib-bio_addr.obj : error LNK2019: unresolved external symbol gai_strerrorA referenced in function addr_strings
libcrypto-shlib-bio_addr.obj : error LNK2019: unresolved external symbol WspiapiFreeAddrInfo referenced in function BIO_ADDRINFO_free
libcrypto-shlib-bio_addr.obj : error LNK2019: unresolved external symbol WspiapiGetAddrInfo referenced in function BIO_lookup
libcrypto-shlib-bss_log.obj : error LNK2019: unresolved external symbol __mingw_vsprintf referenced in function sprintf.constprop.0
libcrypto-shlib-dso_win32.obj : error LNK2001: unresolved external symbol __mingw_vsprintf
libcrypto-shlib-eng_openssl.obj : error LNK2019: unresolved external symbol __mingw_vfprintf referenced in function fprintf
libcrypto-shlib-ui_openssl.obj : error LNK2001: unresolved external symbol __mingw_vfprintf
libcrypto-shlib-http_lib.obj : error LNK2019: unresolved external symbol __mingw_vsscanf referenced in function sscanf
libcrypto-shlib-v3_utl.obj : error LNK2001: unresolved external symbol __mingw_vsscanf
libcrypto-shlib-cryptlib.obj : error LNK2019: unresolved external symbol __imp__vsnwprintf referenced in function OPENSSL_showfatal
libcrypto-shlib-cryptlib.obj : error LNK2019: unresolved external symbol __imp__vsnprintf referenced in function OPENSSL_showfatal
libcrypto-3-x64.dll : fatal error LNK1120: 11 unresolved externals
NMAKE : fatal error U1077: 'cmd' : return code '0x1'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.34.31933\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Stop. 

Running nmake clean deleted the 2328 .obj files revealed by dir /w /s *.obj – this is where using a separate folder for the build would be helpful.

nmake ran for just under 12 minutes. Since I didn’t use the --prefix and --openssldir options when configuring, I tried to set these environment variables before packaging (as described in the docs).

set PREFIX=C:\dev\ssl\package-nmake\OpenSSL
set OPENSSLDIR=C:\dev\ssl\package-nmake\SSL

nmake install

nmake install failed with a permission denied error, which was unexpected given that I set the environment variables as instructed:

...
        cmd /C ""link" /nologo /debug /dll  /nologo /debug @C:\Users\saint\AppData\Local\Temp\nm6D37.tmp /implib:libssl.lib || (DEL /Q libssl-3-x64.* libssl.lib & EXIT 1)"
LINK : libssl-3-x64.dll not found or not built by the last incremental link; performing full link
   Creating library libssl.lib and object libssl.exp
        IF EXIST libssl-3-x64.dll.manifest  "mt" -nologo -manifest libssl-3-x64.dll.manifest -outputresource:libssl-3-x64.dll
        IF EXIST apps\libssl-3-x64.dll DEL /Q /F apps\libssl-3-x64.dll
        IF EXIST test\libssl-3-x64.dll DEL /Q /F test\libssl-3-x64.dll
        IF EXIST fuzz\libssl-3-x64.dll DEL /Q /F fuzz\libssl-3-x64.dll
        COPY libssl-3-x64.dll apps
        1 file(s) copied.
        COPY libssl-3-x64.dll test
        1 file(s) copied.
        COPY libssl-3-x64.dll fuzz
        1 file(s) copied.
*** Installing runtime libraries
Cannot create directory C:/Program Files/OpenSSL: Permission denied
NMAKE : fatal error U1077: 'C:\software\strawberry\perl\bin\perl.exe' : return code '0x2'
Stop.

Here are the commands that were needed. The install step took about 2 minutes (or about 30 sec if output is redirected to disk).

perl Configure VC-WIN64A --prefix=C:/dev/ssl/package-nmake/OpenSSL --openssldir=C:/dev/ssl/package-nmake/SSL

nmake
nmake install

Outstanding Questions

  1. Why don’t the environment variables work for nmake install?

Categories: Windows

Disabling my Desktop’s Power Button

My almost 2-year-old walked into my office this evening and pressed the shiny flashing button at the top of my desktop PC. Unfortunately, that turns out to also be the power button. And there went all my applications and the documents I was working on… I didn’t lose much (other than my cool) but this experience motivated me to venture into a corner of Windows I had not considered using. This

Power and sleep button settings

… has now become…

Power and sleep button settings showing disabled buttons

Categories: Cygwin

curl Failures in Cygwin

If curl fails with error 23 in Cygwin, it is likely that the curl command shipped with Windows is running in the Cygwin terminal instead of the curl binary distributed with Cygwin. To install the Cywin curl command, run the setup executable with these flags:

setup-x86_64.exe -q -P curl

Background

One of the issues I looked into this week was running an AQAvit™ Verification test on Windows and therefore in Cygwin. Here are the environment variables I set and the commands I executed as outlined on the AQAvit™ Verification page.

export TEST_JDK_HOME=/cygdrive/c/java/binaries/jdk/aarch64/jdk-17.0.6+10
export USE_TESTENV_PROPERTIES=true
export JDK_VERSION=17
export BUILD_LIST=openjdk

git clone --depth 1 --branch v0.9.1-release https://github.com/adoptium/aqa-tests.git

cd aqa-tests
./get.sh
./compile.sh

The last command above (compilation) failed on my Surface Pro X with this error:

...
Buildfile: C:\java\aqa\aqa-tests\TKG\scripts\build_tools.xml

build:

clean:
   [delete] Deleting directory C:\java\aqa\aqa-tests\TKG\bin

init:
    [mkdir] Created dir: C:\java\aqa\aqa-tests\TKG\bin

getDependentLibs:
     [exec] --------------------------------------------
     [exec] path is set to /cygdrive/c/java/aqa/aqa-tests/TKG/../TKG/lib
     [exec] task is set to default
     [exec] dependencyList is set to json_simple
     [exec] --------------------------------------------
     [exec] Starting download third party dependent jars
     [exec] --------------------------------------------
     [exec] downloading dependent third party jars to /cygdrive/c/java/aqa/aqa-tests/TKG/../TKG/lib
     [exec] downloading https://repo1.maven.org/maven2/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar
     [exec]   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
     [exec]                                  Dload  Upload   Total   Spent    Left  Speed
     [exec]
     [exec]   0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Warning: Failed to open the file Warning: /cygdrive/c/java/aqa/aqa-tests/TKG/../TKG/lib/json-simple.jar: No
     [exec] Warning: such file or directory
     [exec]
     [exec]   5 23931    5  1371    0     0   4483      0  0:00:05 --:--:--  0:00:05  4509curl: (23) Failure writing output to destination
     [exec] ERROR: downloading https://repo1.maven.org/maven2/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar failed, return code: 5888

BUILD FAILED
C:\java\aqa\aqa-tests\TKG\scripts\build_tools.xml:58: The following error occurred while executing this line:
C:\java\aqa\aqa-tests\TKG\scripts\getDependencies.xml:27: exec returned: 2

I had core.autocrlf set to true when I initially checked out the aqa-tests repo so I suspected the culprit to be a file that didn’t get converted to LF when I ran git add --renormalize as suggested by How do I re-checkout all files in Git to convert from CRLF to LF? – Stack Overflow. I would get errors like “/cygdrive/c/java/aqa/aqa-tests/TKG/scripts/getTestenvProperties.sh: line 14: $’\r’: command not found” and ended up manually changing the line endings using VS Code since there were only 3 files that needed to be changed but I digress…

Looks like curl is being invoked by TKG/getDependencies.pl · adoptium/TKG · GitHub. A search for perl return code 5888 leads to an issue about a Strange error while downloading perl: 5888 · Issue #748 · gugod/App-perlbrew · GitHub. This is helpful because it links to a PR Implement a standard set of error checking of system(). · gugod/App-perlbrew@42415bc · GitHub ensuring that the actual error from curl is displayed to the user. This error is obtaining by shifting the error code right by 8 bits. We get that 5888 >> 8 = 23. The description of error 23 at libcurl – Error Codes is not particularly insightful. However, it does lead me to manually test the curl command and see whether the issue is with curl or with all the build scripts. Sure enough, the curl command fails when given a fully qualified Cygwin path!

$ curl -k -o  /c/java/aqa/aqa-tests/TKG/lib/file.jar https://repo1.maven.org/maven2/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Warning: Failed to open the file /c/java/aqa/aqa-tests/TKG/lib/file.jar: No
Warning: such file or directory
  5 23931    5  1371    0     0   4660      0  0:00:05 --:--:--  0:00:05  4679
curl: (23) Failure writing output to destination

$ curl -k -o  ../file.jar https://repo1.maven.org/maven2/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 23931  100 23931    0     0  84394      0 --:--:-- --:--:-- --:--:-- 84861

Which curl is running? Turns out it’s the native Windows curl command!

$ which curl
/cygdrive/c/WINDOWS/system32/curl

$ curl --version
curl 7.83.1 (Windows) libcurl/7.83.1 Schannel
Release-Date: 2022-05-13
Protocols: dict file ftp ftps http https imap imaps pop3 pop3s smtp smtps telnet tftp
Features: AsynchDNS HSTS IPv6 Kerberos Largefile NTLM SPNEGO SSL SSPI UnixSockets

I realize there must be a native Cygwin curl package so I install it using this command: \software\setup-x86_64.exe -q -P curl

Installing curl

I end up needing to open a new shell to get it to be picked up when building. That fixes the problem (this version successfully writes the downloaded file to disk)! Here’s the version information for the curl utility installed by Cygwin:

$ which curl
/usr/bin/curl

$ /usr/bin/curl --version
curl 7.87.0 (x86_64-pc-cygwin) libcurl/7.87.0 OpenSSL/1.1.1s zlib/1.2.13 brotli/1.0.9 zstd/1.5.2 libidn2/2.3.4 libpsl/0.21.2 (+libidn2/2.3.4) libssh2/1.10.0 nghttp2/1.51.0 libgsasl/2.2.0
Release-Date: 2022-12-21
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli Debug gsasl GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL threadsafe TLS-SRP TrackMemory UnixSockets zstd