stripping lto flags doesn't work as expected

Bug #2002076 reported by Shengjing Zhu
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
dh-golang (Ubuntu)
Invalid
Undecided
Unassigned
dpkg (Ubuntu)
Fix Released
Undecided
Unassigned

Bug Description

In dh-golang, we use dpkg's C flags as Go's CGO flags. When dpkg's LTO feature is enabled, the LTO C flags may pass to CGO as well. But Go's linker doesn't support LTO. So in dh-golang, we implemented a workround to strip LTO flag[1].

[1] https://salsa.debian.org/go-team/packages/dh-golang/-/commit/501517bca24c155bdd3ed706ad413a22c625c7a8

```
$bf->strip($flag, "-ffat-lto-objects -flto=auto");
```

This works well in Debian, but it turns out not robust for Ubuntu.

In Ubuntu, we get such C flags:

```
$ dpkg-buildflags --get CFLAGS
-g -O2 -ffile-prefix-map=[redacted]=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security

```

It has two duplicated `-flto=auto -ffat-lto-objects`. So dh-golang's code doesn't handle it robustly. One `-flto=auto -ffat-lto-objects` set is still passed to CGO. This causes link error.

Tags: fr-3163
Shengjing Zhu (zhsj)
description: updated
Revision history for this message
Shengjing Zhu (zhsj) wrote :

$bf->strip first split its input (here is `-ffat-lto-objects -flto=auto`), then use for loop to strip every flag.

```
    my ($self, $flag, $value, $src, $maint) = @_;
    foreach my $tostrip (split(/\s+/, $value)) {
        next unless length $tostrip;
        $self->{flags}->{$flag} =~ s/(^|\s+)\Q$tostrip\E(\s+|$)/ /g;
    }

```

It does use `g` flag in regex, (maybe want to strip all duplicated flag?)

In first loop, for `-ffat-lto-objects`, it does strip two `-ffat-lto-objects`. Then the flag becomes `-flto=auto -flto=auto`.

Then in second loop, it stops working. Because there's only one space between two `-flto=auto`. However the regex expects space before and after one token. So it only strips one `-flto=auto`.

See https://regex101.com/r/AgDMzv/1 for regex debug.

Shengjing Zhu (zhsj)
tags: added: fr-3163
Revision history for this message
Shengjing Zhu (zhsj) wrote :

The best is to write a smart regexp in dpkg. Or just workaround(yeah, workaround on workarund, the lto strip is already a workaround) like:

```
diff -Nru dh-golang-1.59/lib/Debian/Debhelper/Buildsystem/golang.pm dh-golang-1.59ubuntu1/lib/Debian/Debhelper/Buildsystem/golang.pm
--- dh-golang-1.59/lib/Debian/Debhelper/Buildsystem/golang.pm 2022-09-25 11:28:07.000000000 +0000
+++ dh-golang-1.59ubuntu1/lib/Debian/Debhelper/Buildsystem/golang.pm 2023-01-06 09:59:50.000000000 +0000
@@ -380,6 +380,8 @@
     foreach my $flag (@flags) {
         if (! exists $ENV{"CGO_" . $flag}) {
             $bf->strip($flag, "-ffat-lto-objects -flto=auto");
+ # strip twice to workaround #1028044
+ $bf->strip($flag, "-ffat-lto-objects -flto=auto");
             # https://golang.org/issues/54313
             # https://github.com/golang/go/commit/365ca694
             $bf->strip($flag, "-fstack-protector-strong");
```

Revision history for this message
Shengjing Zhu (zhsj) wrote (last edit ):

I'm inclined to do nothing in dh-golang.

This bug is caused by:

+ Ubuntu added lto flags twice, which I filled another bug at LP #2002201 and I have a MP for it.
+ dpkg $bf-strip is not robust, which I filled at https://bugs.debian.org/1028044, and is already fixed in trunk.

Either one is fixed, this bug no longer exists.

Revision history for this message
Shengjing Zhu (zhsj) wrote :

LP #2002201 is fixed. So let's make this invalid.

Changed in dh-golang (Ubuntu):
status: New → Invalid
Shengjing Zhu (zhsj)
Changed in dpkg (Ubuntu):
status: New → Fix Committed
Shengjing Zhu (zhsj)
Changed in dpkg (Ubuntu):
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.