Retro68 icon indicating copy to clipboard operation
Retro68 copied to clipboard

std::regex() not working correctly

Open programmingkidx opened this issue 9 months ago • 7 comments

There is a problem with the regex() function. It does not seem to work. Instead it throws a std::bad_cast when used. I used two different regular expressions and both failed on Mac OS 9. They do work on Mac OS 12.3. The program is compiled as PowerPC. I ran this program on Mac OS 12.3 and using the online GDB compiler without problem. I suspect issues with regex().

This is the program I used for testing:

#include <cstdio>
#include <iostream>
#include <stdexcept>
#include <fstream>
#include <string>
#include <regex>

using namespace std;

// Saves to the file crash.txt any uncaught exceptions
void myTerminateHandler() {
    try {
        // Re-throw the current uncaught exception
        throw;
    } catch (exception& e) {
        ofstream out("crash.txt");
        out << "Uncaught exception: " << e.what() << '\n';
        out.close();
    } catch (...) {
        ofstream out("crash.txt");
        out << "Unknown uncaught exception.\n";
        out.close();
    }
}

// Write to a checkpoint.txt file a checkpoint number to indicate where things stopped working
void saveCheckPoint(int i) {
    FILE * myfile;
    myfile = fopen("checkpoint.txt", "a+");
    if(!myfile) {
        printf("Error: can't open checkpoint.text file\n");
        getchar();
    }
    fprintf(myfile, "checkpoint %d\n", i);
    fclose(myfile);
}
 
void match_and_print(const string& text, const regex& pattern)
{
    sregex_iterator it(text.begin(), text.end(), pattern), it_end;
    int count = 0;
    for (; it != it_end; ++it)
    {
        const smatch& match = *it;
        cout << ++count << ". " << match.str() << '\n';
    }
    cout << (count ? "\n" : "no match found\n\n");
}
 
int main()
{
    int counter = 1;
    saveCheckPoint(counter++);
    set_terminate(myTerminateHandler);
    string text = "Hello, World! 12345";
    saveCheckPoint(counter++);

    // Matches one or more digits
    //string pattern_text = "\\d+";
    string pattern_text = "\\w+!";
    cout << "digits (" << pattern_text << "):\n";
    saveCheckPoint(counter++);  // 3
    auto pattern = regex(pattern_text);
    saveCheckPoint(counter++); //4
    match_and_print(text, pattern);
    saveCheckPoint(counter++);   // 5
}

Since there is no terminal on Mac OS 9 I had to save all errors to file in order to view them. The saveCheckPoint() function is used to pinpoint where execution stops working. If someone knows a better what to debug on Mac OS 9, please let me know.

programmingkidx avatar Mar 01 '25 22:03 programmingkidx

There is no terminal, but there is the RetroConsole library which can be used for basic stdin/stdout support. For real debugging, MacsBug is so far all there is (there must be some ways to get gdb to do something useful, but so far I've only encountered pain).

Some vague ideas on how to debug this...

  • if there's a bad_cast, maybe there is a problem with typeinfo and dynamic_cast?
  • look at the source code and figure out if, where and why libstdc++'s regex implementation does runtime type casts
  • ?

autc04 avatar Mar 02 '25 12:03 autc04

I think the problem is with this member initialization list:

  template<typename _TraitsT>
    _Compiler<_TraitsT>::
    _Compiler(const _CharT* __b, const _CharT* __e,
	      const typename _TraitsT::locale_type& __loc, _FlagT __flags)
    : _M_flags(_S_validate(__flags)),
      _M_scanner(__b, __e, _M_flags, __loc),
      _M_nfa(make_shared<_RegexT>(__loc, _M_flags)),
      _M_traits(_M_nfa->_M_traits),
     _M_ctype(std::use_facet<_CtypeT>(__loc))
    {

It is located in the file Retro68-build/toolchain/powerpc-apple-macos/include/c++/12.2.0/bits/regex_compiler.tcc. I used a try-catch block to verify the exception is being thrown here. I don't know which one is throwing the exception, but I bet it is use_facet<_CtypeT> because the documentation for it states it can throw a bad_cast. https://en.cppreference.com/w/cpp/locale/use_facet

programmingkidx avatar Mar 02 '25 21:03 programmingkidx

Gcc 14 on Mac OS 12 also has a problem with std::locale. I believe it is related to this issue. I made the bug report here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119105

programmingkidx avatar Mar 04 '25 19:03 programmingkidx

For real debugging, MacsBug is so far all there is (there must be some ways to get gdb to do something useful, but so far I've only encountered pain).

Sad! I wish there was a way to debug PowerPC programs from QEMU/Sheepshaver from my Windows host

void2012 avatar Mar 10 '25 19:03 void2012

@void2012 I am guessing you want a source code debugger and not an assembly debugger like macsbug.

@autc04 Maybe adding a source code debugger is a possible Google Summer of Code project. Interested?

https://summerofcode.withgoogle.com

programmingkidx avatar Mar 10 '25 20:03 programmingkidx

I want both, actually. Doing some reverse engineering stuff.

void2012 avatar Mar 10 '25 20:03 void2012

macsbug is what you want for assembly language viewing. I am pretty sure it ran on qemu-system-ppc with Mac OS 9.

programmingkidx avatar Mar 10 '25 20:03 programmingkidx