Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows+MSVC] Debug run hangs trying to start, and cannot be killed except by OS #69

Closed
BucketOfNubbins opened this issue Oct 20, 2024 · 2 comments
Labels
bug Something isn't working Critical

Comments

@BucketOfNubbins
Copy link

BucketOfNubbins commented Oct 20, 2024

I have a project where I will create many separate executable files. One file for each practice problem I am doing. Running each of the files normally works just fine. However debugging the rngTest.zig file in particular causes the hanging / can't connect behavior.

connecting

Trying to stop the program from within CLion with the stop button in the top right greys out the stop button, but the program still runs. As shown by if I go to run the program again.

still_running

The best way to actually stop the process fully is to shut down CLion entirely and let the OS clean it up. As CLion seems unable to terminate it.

try_terminate

try_detach

I have only let CLion try to kill the program for a few minutes, I don't know if it will eventually work but it seems frozen to me.

Below is the build file for this project.

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});

    const optimize = b.standardOptimizeOption(.{});

    //====================================================================================

    const mainExe = b.addExecutable(.{
        .name = "Main",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    b.installArtifact(mainExe);
    const run_main_cmd = b.addRunArtifact(mainExe);
    run_main_cmd.step.dependOn(b.getInstallStep());
    const run_main_step = b.step("main", "Run the app");
    run_main_step.dependOn(&run_main_cmd.step);

    //====================================================================================

    const velkominExe = b.addExecutable(.{
        .name = "velkomin",
        .root_source_file = b.path("src/velkomin.zig"),
        .target = target,
        .optimize = optimize,
    });

    b.installArtifact(velkominExe);
    const run_velkomin_cmd = b.addRunArtifact(velkominExe);
    run_velkomin_cmd.step.dependOn(b.getInstallStep());
    const run_velkomin_step = b.step("velkomin", "Run the app");
    run_velkomin_step.dependOn(&run_velkomin_cmd.step);

    //====================================================================================

    const rngTestExe = b.addExecutable(.{
        .name = "rngTest",
        .root_source_file = b.path("src/rngTest.zig"),
        .target = target,
        .optimize = optimize,
    });

    b.installArtifact(rngTestExe);
    const run_rngTest_cmd = b.addRunArtifact(rngTestExe);
    run_rngTest_cmd.step.dependOn(b.getInstallStep());
    const run_rngTest_step = b.step("rngTest", "Run the app");
    run_rngTest_step.dependOn(&run_rngTest_cmd.step);

    //====================================================================================

}

Below is one of my build configurations to run one of the files. The other build configs follow the same format, just with changed names.

build_configuration

The other files work fine, and I can debug them. It is just the "rngTest.zig" that I cannot debug. I am not sure exactly what causes it, as I don't know how to reproduce the bug yet. Though it is worth noting "rngTest.zig" is the only file to take in user input.

Below is the code for "rngTest.zig"

const std = @import("std");

pub fn main() !void {
    var br = std.io.bufferedReader(std.io.getStdIn().reader());
    var bw = std.io.bufferedWriter(std.io.getStdOut().writer());
    const in = br.reader();
    const out = bw.writer();

    defer bw.flush() catch {};

    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();

    const alloc = arena.allocator();

    var input = std.ArrayList(u8).init(alloc);

    try in.readUntilDelimiterArrayList(&input, '\n', std.math.maxInt(usize));

    var a: i64 = undefined;
    var b: i64 = undefined;
    var x0: i64 = undefined;
    var n: i64 = undefined;
    var m: i64 = undefined;

    var iter = std.mem.splitAny(u8, input.items, &[_]u8{' '});

    var index: u8 = 0;
    while (iter.next()) |number| {
        switch (index) {
            0 => a = try std.fmt.parseInt(i64, number, 10),
            1 => b = try std.fmt.parseInt(i64, number, 10),
            2 => x0 = try std.fmt.parseInt(i64, number, 10),
            3 => n = try std.fmt.parseInt(i64, number, 10),
            4 => m = try std.fmt.parseInt(i64, number, 10),
            else => unreachable,
        }
        index += 1;
    }

    var result: i64 = undefined;
    const an = try modPow(a, n, m);
    const part1 = try std.math.mod(i64, an * x0, m);
    var part2 = try fastGeometricSeries(a, n, an, m);
    part2 = try std.math.mod(i64, b * part2, m);
    result = try std.math.mod(i64, part1 + part2, m);
    try out.print("{}\n", .{result});
}

const MathError = error{
    NoModularInverse,
};

// sum_{i=0}{n-1} a^i mod m
fn fastGeometricSeries(a: i64, n: i64, an: i64, m: i64) !i64 {
    // with mod inverse
    const inverse = modularInverse(a - 1, m);
    var answer: i64 = undefined;
    if (inverse != MathError.NoModularInverse) {
        // std.debug.print("Has inverse\n", .{});
        const inv = try inverse;
        answer = try std.math.mod(i64, ((an - 1) * inv), m);
    } else {
        // std.debug.print("{} {} {}\n", .{ a, n, m });
        answer = try recursiveGeometricSeries(a, n, m);
        // std.debug.print("{}\n", .{answer});
    }
    return answer;
}

fn recursiveGeometricSeries(a: i64, nn: i64, m: i64) !i64 {
    var n = nn;
    if (n == 1) {
        return 1;
    } else {
        var answer: i64 = 0;
        if (n & 1 == 1) {
            answer += try modPow(a, n - 1, m);
            n -= 1;
        }
        const n2 = n >> 1;
        var factor = try modPow(a, n2, m);
        factor += 1;
        if (factor == m) {
            return 0;
        }
        const half = try recursiveGeometricSeries(a, n2, m);
        answer += try std.math.mod(i64, half * factor, m);
        answer = try std.math.mod(i64, answer, m);
        // std.debug.print("{} {} {} -> {}\n", .{a, nn, m, answer});
        return answer;
    }
}

fn modularInverse(a: i64, m: i64) !i64 {
    const euclid = try eEuclid(a, m);
    if (euclid[0] != 1) {
        return MathError.NoModularInverse;
    } else {
        var inverse = try std.math.mod(i64, euclid[1], m);
        inverse += m;
        return try std.math.mod(i64, inverse, m);
        // return ((euclid[1] % m) + m) % m;
    }
}

fn modPow(aa: i64, bb: i64, m: i64) !i64 {
    var a = aa;
    var b = bb;
    var res: i64 = 1;
    while (b != 0) {
        if ((b & 1) == 1) {
            res *= a;
            res = try std.math.mod(i64, res, m);
            // res %= p;
        }
        a *= a;
        a = try std.math.mod(i64, a, m);
        // a %= p;
        b >>= 1;
    }
    return res;
}

fn eEuclid(a: i64, b: i64) ![3]i64 {
    var x: i64 = 1;
    var y: i64 = 0;
    var x1: i64 = 0;
    var y1: i64 = 1;
    var a1: i64 = a;
    var b1: i64 = b;
    var t: i64 = undefined;
    while (b1 != 0) {
        const q = try std.math.divFloor(i64, a1, b1);
        // const q = a1 / b1;
        t = x1;
        x1 = x - q * x1;
        x = t;
        t = y1;
        y1 = y - q * y1;
        y = t;
        t = b1;
        b1 = a1 - q * b1;
        a1 = t;
    }
    return [3]i64{ a1, try std.math.mod(i64, x + b, b), y };
}

zig version:
0.14.0-dev.1930+4a2a0f50c

@FalsePattern
Copy link
Owner

I'll look into both this issue and #68 once I have more free time, I'm just overloaded with IRL tasks at the moment.

For now, if you really urgently need debugging for zig, try using vscode with the c++ plugin (it provides the msvc debug adapter), that should still work.

@FalsePattern FalsePattern added bug Something isn't working Critical labels Oct 22, 2024
@FalsePattern FalsePattern changed the title Debug run hangs trying to start, and cannot be killed except by OS [Windows+MSVC] Debug run hangs trying to start, and cannot be killed except by OS Oct 22, 2024
@FalsePattern
Copy link
Owner

FalsePattern commented Oct 25, 2024

Should be fixed in 19.1.0

@FalsePattern FalsePattern added waiting for response Bug is probably fixed, waiting for verification by reporter and removed waiting for response Bug is probably fixed, waiting for verification by reporter labels Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Critical
Projects
None yet
Development

No branches or pull requests

2 participants