horizon-eda / horizon

Horizon is a free EDA package
https://horizon-eda.org/
GNU General Public License v3.0
1.08k stars 79 forks source link

"unknown error" when trying to generate fabrication output #738

Closed ii8 closed 9 months ago

ii8 commented 9 months ago

Using the ODB++ fabrication output tool does not generate any files but instead reports "unknown error" in a little dialog box. I've tried looking in the console output but there is no information there either about what the error might be caused by. Generating gerber files on the other hand works fine.

I have some big PTHs with vias in their ring as mounting holes that are all on an "EARTH" net but not connected to each other with copper so the preflight checks fail. I don't know if that is possibly relevant or could cause this kind of error, or if that is even the right way to add plated mounting holes.

carrotIndustries commented 9 months ago

To debug this further, either attach GDB and tell it to catch exceptions or post a minimum example that shows this bug.

ii8 commented 9 months ago

This doesn't look very useful to me, but I don't know how the whole glib stuff works. Do I need to compile a horizon with debug symbols for this to be useful?

(gdb) catch throw
Catchpoint 1 (throw)
(gdb) set follow-fork-mode child
(gdb) r
Starting program: /usr/bin/horizon-eda

Thread 2.1 "horizon-imp" hit Catchpoint 1 (exception thrown), 0x00007ffff7ce8d70 in __cxa_throw () from /lib/libstdc++.so.6
(gdb) bt
#0  0x00007ffff7ce8d70 in __cxa_throw () from /lib/libstdc++.so.6
#1  0x00007ffff61b827c in Glib::ConvertError::throw_func(_GError*) () from /lib/libglibmm-2.4.so.1
#2  0x00007ffff61dad28 in Glib::Error::throw_exception(_GError*) () from /lib/libglibmm-2.4.so.1
#3  0x00007ffff61c0b3e in Glib::convert_with_fallback(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::
__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::al
locator<char> > const&) () from /lib/libglibmm-2.4.so.1
#4  0x00005555560e96b2 in ?? ()
#5  0x00005555560e9882 in ?? ()
#6  0x00005555560ca7ec in ?? ()
#7  0x0000555556217226 in ?? ()
#8  0x00007ffff61d5a58 in Glib::SignalProxyNormal::slot0_void_callback(_GObject*, void*) () from /lib/libglibmm-2.4.so.1
#9  0x00007ffff55e3270 in g_closure_invoke () from /lib/libgobject-2.0.so.0
#10 0x00007ffff55f6744 in ?? () from /lib/libgobject-2.0.so.0
#11 0x00007ffff55fd095 in g_signal_emit_valist () from /lib/libgobject-2.0.so.0
#12 0x00007ffff55fd25f in g_signal_emit () from /lib/libgobject-2.0.so.0
#13 0x00007ffff4ecd860 in ?? () from /lib/libgtk-3.so.0
#14 0x00007ffff5a48f7e in Gtk::Button_Class::released_callback(_GtkButton*) () from /lib/libgtkmm-3.0.so.1
#15 0x00007ffff55e3469 in ?? () from /lib/libgobject-2.0.so.0
#16 0x00007ffff55fd05f in g_signal_emit_valist () from /lib/libgobject-2.0.so.0
#17 0x00007ffff55fd25f in g_signal_emit () from /lib/libgobject-2.0.so.0
#18 0x00007ffff4ecd620 in ?? () from /lib/libgtk-3.so.0
#19 0x00007ffff4e90069 in ?? () from /lib/libgtk-3.so.0
#20 0x00007ffff55e3469 in ?? () from /lib/libgobject-2.0.so.0
#21 0x00007ffff55fd05f in g_signal_emit_valist () from /lib/libgobject-2.0.so.0
#22 0x00007ffff55fd25f in g_signal_emit () from /lib/libgobject-2.0.so.0
#23 0x00007ffff4f9ecd6 in ?? () from /lib/libgtk-3.so.0
#24 0x00007ffff55e6642 in g_cclosure_marshal_VOID__BOXEDv () from /lib/libgobject-2.0.so.0
#25 0x00007ffff55e3469 in ?? () from /lib/libgobject-2.0.so.0
#26 0x00007ffff55fd05f in g_signal_emit_valist () from /lib/libgobject-2.0.so.0
#27 0x00007ffff55fd25f in g_signal_emit () from /lib/libgobject-2.0.so.0
#28 0x00007ffff4f96f53 in ?? () from /lib/libgtk-3.so.0
#29 0x00007ffff4f9e6db in ?? () from /lib/libgtk-3.so.0
#30 0x00007ffff4fa1b75 in ?? () from /lib/libgtk-3.so.0
#31 0x00007ffff4f67b41 in gtk_event_controller_handle_event () from /lib/libgtk-3.so.0
#32 0x00007ffff51301dd in ?? () from /lib/libgtk-3.so.0
#33 0x00007ffff5b10344 in Gtk::Widget::on_button_release_event(_GdkEventButton*) () from /lib/libgtkmm-3.0.so.1
#34 0x00007ffff5b0a004 in Gtk::Widget_Class::button_release_event_callback(_GtkWidget*, _GdkEventButton*) () from /lib/libgtkmm-3.0.so.1
#35 0x00007ffff4e8e704 in ?? () from /lib/libgtk-3.so.0
#36 0x00007ffff55e3469 in ?? () from /lib/libgobject-2.0.so.0
#37 0x00007ffff55fc49e in g_signal_emit_valist () from /lib/libgobject-2.0.so.0
#38 0x00007ffff55fd25f in g_signal_emit () from /lib/libgobject-2.0.so.0
#39 0x00007ffff513ecb4 in ?? () from /lib/libgtk-3.so.0
#40 0x00007ffff4fe80fe in ?? () from /lib/libgtk-3.so.0
--Type <RET> for more, q to quit, c to continue without paging--
#41 0x00007ffff4fe8f3a in gtk_main_do_event () from /lib/libgtk-3.so.0
#42 0x00007ffff6547d23 in ?? () from /lib/libgdk-3.so.0
#43 0x00007ffff6579402 in ?? () from /lib/libgdk-3.so.0
#44 0x00007ffff4531dad in g_main_context_dispatch () from /lib/libglib-2.0.so.0
#45 0x00007ffff4532058 in ?? () from /lib/libglib-2.0.so.0
#46 0x00007ffff45320ec in g_main_context_iteration () from /lib/libglib-2.0.so.0
#47 0x00007ffff46fbedd in g_application_run () from /lib/libgio-2.0.so.0
#48 0x0000555555d6b591 in ?? ()
#49 0x000055555596eae0 in ?? ()
#50 0x00007ffff7f69ffb in libc_start_main_stage2 (main=0x55555596e290, argc=6, argv=0x7fffffffdfe8) at src/env/__libc_start_main.c:94
#51 0x000055555598d17b in ?? ()
#52 0x0000000000000006 in ?? ()
#53 0x00007fffffffe35d in ?? ()
#54 0x0000000000000000 in ?? ()
carrotIndustries commented 9 months ago

This doesn't look very useful to me, but I don't know how the whole glib stuff works. Do I need to compile a horizon with debug symbols for this to be useful?

Will definitely help. I'd have at least guessed that it'd show the binary name rather than just ??

ii8 commented 9 months ago

They're functions that are local to the object file that contains them, they aren't dynamically linked so the symbol names can be stripped. There may also be some functions that got inlined in which case not even a ?? will show up even though you have a function call in the source code.

carrotIndustries commented 9 months ago

Do you have any unusual net names or reference designators in your design? The ODB++ export removes any non-ASCII characters by means of Glib::convert_with_fallback which is the function that's throwing the exception in your case.

ii8 commented 9 months ago

No, all my designators and netnames are ASCII only. I do have package names with the diameter symbol though: ⌀ And the ohm symbol is in value fields of resistors.

I managed to eventually compile horizon with debug symbols on my potato PC:

(gdb) bt
#0  0x00007ffff7ce8d70 in __cxa_throw () from /lib/libstdc++.so.6
#1  0x00007ffff61b827c in Glib::ConvertError::throw_func(_GError*) () from /lib/libglibmm-2.4.so.1
#2  0x00007ffff61dad28 in Glib::Error::throw_exception(_GError*) () from /lib/libglibmm-2.4.so.1
#3  0x00007ffff61c0b3e in Glib::convert_with_fallback(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::
__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::al
locator<char> > const&) () from /lib/libglibmm-2.4.so.1
#4  0x00005555561261d2 in horizon::ODB::utf8_to_ascii (s="ppp") at /usr/include/c++/12.2/bits/basic_string.tcc:238
#5  0x00005555561263a2 in horizon::ODB::make_legal_entity_name (s="ppp") at src/export_odb/odb_util.cpp:57
#6  0x0000555556107567 in horizon::get_step_name (block=...) at src/export_odb/odb_export.cpp:53
#7  horizon::export_odb (brd=..., settings=...) at src/export_odb/odb_export.cpp:64
#8  0x000055555625b441 in horizon::FabOutputWindow::generate (this=0x555558a94ec0) at src/imp/fab_output_window.cpp:408

The "ppp" string is the project name.

carrotIndustries commented 9 months ago

Try applying this commit https://github.com/horizon-eda/horizon/commit/bc17786e49c6fbe26576695f8bcdbe0cd262646b to see what the error is (rather than unknown error)

ii8 commented 9 months ago

Ok, looks like it's recompiling everything for some reason so might take a little while.

ii8 commented 9 months ago

How come the std::string call is around the "Error: " string instead of the e.what() like in the catch just above?

odb_done_revealer_controller.show_error("Error: " + std::string(e.what()));

vs

odb_done_revealer_controller.show_error(std::string("Error: ") + e.what()); 
carrotIndustries commented 9 months ago

in std::exception , what returns a const char* , but in Glib::Error it returns a Glib::ustring . The std::string around the string literal isn't strictly necessary.

ii8 commented 9 months ago

It reports 'Error: Conversion from character set “utf-8” to “ascii//TRANSLIT” is not supported'

It's possibly relevant that I am using musl libc, so there might be some differences with locale and iconv behavior

carrotIndustries commented 9 months ago

It reports 'Error: Conversion from character set “utf-8” to “ascii//TRANSLIT” is not supported'

Interesting, which distro are you using? Maybe try installing libiconv.

ii8 commented 9 months ago

https://wiki.musl-libc.org/functional-differences-from-glibc.html#iconv

Transliterations (//TRANSLIT suffix) are not supported.

Indeed when I remove the //TRANSLIT part it works.

carrotIndustries commented 9 months ago

Indeed when I remove the //TRANSLIT part it works.

Ok, so I think we need to detect whether the libc supports //TRANSLIT either at runtime or config-time to fix this issue and retain transliteration for everyone else.

As far as I could tell, build time should be sufficient.

ii8 commented 9 months ago

It looks like the transliterations are a non-POSIX glibc extension, so the simple fix would be to just not use it. It also looks like the behavior of //TRANSLIT is locale specific, which is also pretty bad and if you were pedantic it probably shouldn't be used just for that.

To retain transliteration, the complete and most proper fix for consistent behavior regardless of libc would be to drop //TRANSLIT and instead implement transliterations directly in horizon.

The hacky fix is what you suggest, have libc specific behavior, build time would be sufficient technically but I should note that musl devs disapprove of build-time feature assumptions: https://wiki.musl-libc.org/faq.html

It’s a bug to assume a certain implementation has particular properties rather than testing. So far, every time somebody’s asked for this with a particular usage case in mind, the usage case was badly wrong, and would have broken support for the next release of musl. The official explanation: http://openwall.com/lists/musl/2013/03/29/13

This is not a particularly crucial feature so maybe the hacky option is ok but I'll have a look at how the transliterations work later, maybe it's really easy and wouldn't be much work to do it properly.

ii8 commented 9 months ago

So the musl people say they may implement the transliterations in the future, so my recommendation would be to do a runtime check so that if and when they are supported it will start working automatically. This would also mean that it works for any other libc without having to keep a list of who supports what up to date. Slight difference in behavior, while not ideal, shouldn't be too much of an issue for this sort of thing, and it wouldn't be really ideal to duplicate the functionality either anyway.

carrotIndustries commented 9 months ago

See if this commit fixes it for you https://github.com/horizon-eda/horizon/commit/6810d63be6905ae505c0d921b2fdf19a879d92a0

Since there appears to be runtime component to iconv, a runtime check is probably the better way.

ii8 commented 9 months ago

Yes that works.