linux-surface / iptsd

Userspace daemon for Intel Precise Touch & Stylus
GNU General Public License v2.0
86 stars 39 forks source link

[SP8] Failure during startup #124

Closed aktowns closed 1 year ago

aktowns commented 1 year ago

Heya!

I'm using version 1.2.0-1 from the arch repository on 6.2.10-arch1-1-surface with kde, Touch isn't working, looking at systemd status can see the iptsd daemon is failing on an assert with the following:

Apr 20 22:42:25 surfacepro iptsd[18177]: [22:42:25.373] [info] Metadata:
Apr 20 22:42:25 surfacepro iptsd[18177]: [22:42:25.373] [info] rows=46, columns=68
Apr 20 22:42:25 surfacepro iptsd[18177]: [22:42:25.373] [info] width=27389, height=18259
Apr 20 22:42:25 surfacepro iptsd[18177]: [22:42:25.373] [info] transform=[408.79105,0,0,0,405.75555,0]
Apr 20 22:42:25 surfacepro iptsd[18177]: [22:42:25.373] [info] unknown=1, [178,182,180,1,178,182,180,1,90,171,100,20,172,177,175,2]
Apr 20 22:42:25 surfacepro iptsd[18177]: [22:42:25.374] [info] Connected to device 045E:0C37
Apr 20 22:42:27 surfacepro iptsd[18177]: iptsd: /usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:427: Eigen::DenseCoeffsBase<type-parameter-0-0, 1>::Scalar &Eigen::DenseCoeffsBase<Eigen::Array<double, -1, -1, 1>, 1>::operator()>
Apr 20 22:42:27 surfacepro systemd[1]: iptsd@dev-hidraw0.service: Main process exited, code=dumped, status=6/ABRT
StollD commented 1 year ago

Could you post the full second to last line? It looks like it is truncated, because you are copying out of a pager (when you press the right arrow key it should show the rest of it).

Also, does iptsd-dump work? Could you generate a binary log so I can reproduce this?

$ sudo iptsd-dump $(iptsd-find-hidraw) sp8-crash.bin

Run this command, touch the screen or use the stylus once, then press Ctrl-C and upload the file it created here.

aktowns commented 1 year ago

Oops sorry thought i grabbed it all

iptsd: /usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:427: Eigen::DenseCoeffsBase<type-parameter-0-0, 1>::Scalar &Eigen::DenseCoeffsBase<Eigen::Array<double, -1, -1, 1>, 1>::operator()(Eigen::Index) [Derived = Eigen::Array<double, -1, -1, 1>, Level = 1]: Assertion `index >= 0 && index < size()' failed.

The attached dump: sp8-crash.zip

StollD commented 1 year ago

That data sadly doesn't trigger the issue for me. Could it have been a fluke? What happens when you restart iptsd?

If you locally have a safe way to reproduce it, another thing you could try would be generating a core dump.

$ gdb /usr/bin/iptsd
(gdb) catch throw
(gdb) run /dev/hidrawN

[trigger the error here]

(gdb) generate-core-file

Then upload the core.XXXX file it produces in the current working directory.

(It might be neccessary for you to build iptsd down the road because I am not sure how much useful information the core dump of an iptsd binary that was built with optimizations will have, but for now, this should be fine)

aktowns commented 1 year ago

I can't seem to replicate it at all with a local build under gdb, it works fine :(

I was able to replicate it with the pacman package version but unfortunately i suspect it wont be very helpful

[11:12:10.482] [info] Metadata:
[11:12:10.482] [info] rows=46, columns=68
[11:12:10.482] [info] width=27389, height=18259
[11:12:10.482] [info] transform=[408.79105,0,0,0,405.75555,0]
[11:12:10.482] [info] unknown=1, [178,182,180,1,178,182,180,1,90,171,100,20,172,177,175,2]
[11:12:10.482] [info] Connected to device 045E:0C37
iptsd: /usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:427: Eigen::DenseCoeffsBase<type-parameter-0-0, 1>::Scalar &Eigen::DenseCoeffsBase<Eigen::Array<double, -1, -1, 1>, 1>::operator()(Eigen::Index) [Derived = Eigen::Array<double, -1, -1, 1>, Level = 1]: Assertion `index >= 0 && index < size()' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff79b88ec in ?? () from /usr/lib/libc.so.6
(gdb) bt
#0  0x00007ffff79b88ec in ?? () from /usr/lib/libc.so.6
#1  0x00007ffff7969ea8 in raise () from /usr/lib/libc.so.6
#2  0x00007ffff795353d in abort () from /usr/lib/libc.so.6
#3  0x00007ffff795345c in ?? () from /usr/lib/libc.so.6
#4  0x00007ffff79629f6 in __assert_fail () from /usr/lib/libc.so.6
#5  0x000055555559cfcd in ?? ()
#6  0x00005555555952a8 in ?? ()
#7  0x000055555558043d in ?? ()
#8  0x00005555555800b3 in ?? ()
#9  0x0000555555579342 in ?? ()
#10 0x00007ffff7954790 in ?? () from /usr/lib/libc.so.6
#11 0x00007ffff795484a in __libc_start_main () from /usr/lib/libc.so.6
#12 0x0000555555565995 in ?? ()

I've attached the core file just incase, i'll keep trying to see if i can get the debug version to fail in the same way core.zip

aktowns commented 1 year ago

I don't know if this is the same error, but did catch a seg fault on a reboot

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055f6f1f8e8a5 in iptsd::contacts::detection::convolution::impl::run_3x3<Eigen::Array<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, 3, 3, 1, 3, 3> >(Eigen::DenseBase<Eigen::Array<double, -1, -1, 1, -1, -1> > const&, Eigen::DenseBase<Eigen::Matrix<double, 3, 3, 1, 3, 3> > const&, Eigen::DenseBase<Eigen::Array<double, -1, -1, 1, -1, -1> >&)::{lambda(long, long, long)#2}::operator()(long, long, long) const (dy=<optimized out>, dx=<optimized out>, 
    i=<optimized out>, __closure=<optimized out>) at ../src/contacts/detection/algorithms/optimized/convolution.3x3-extend.hpp:49
49          return in.coeff(index);
(gdb) bt
#0  0x000055f6f1f8e8a5 in iptsd::contacts::detection::convolution::impl::run_3x3<Eigen::Array<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, 3, 3, 1, 3, 3> >(Eigen::DenseBase<Eigen::Array<double, -1, -1, 1, -1, -1> > const&, Eigen::DenseBase<Eigen::Matrix<double, 3, 3, 1, 3, 3> > const&, Eigen::DenseBase<Eigen::Array<double, -1, -1, 1, -1, -1> >&)::{lambda(long, long, long)#2}::operator()(long, long, long) const (dy=<optimized out>, dx=<optimized out>, 
    i=<optimized out>, __closure=<optimized out>) at ../src/contacts/detection/algorithms/optimized/convolution.3x3-extend.hpp:49
#1  iptsd::contacts::detection::convolution::impl::run_3x3<Eigen::Array<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, 3, 3, 1, 3, 3> > (in=..., kernel=..., out=...)
    at ../src/contacts/detection/algorithms/optimized/convolution.3x3-extend.hpp:62
#2  0x000055f6f1f950de in iptsd::contacts::detection::convolution::run<Eigen::Array<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, 3, 3, 1, 3, 3> > (out=..., kernel=..., in=...)
    at ../src/contacts/detection/algorithms/convolution.hpp:91
#3  iptsd::contacts::detection::Detector<double, double>::detect<-1, -1> (this=0x7ffd99beac10, heatmap=..., contacts=std::vector of length 0, capacity 0) at ../src/contacts/detection/detector.hpp:115
#4  0x000055f6f1f5ee78 in iptsd::contacts::Finder<double, double>::find<-1, -1> (contacts=std::vector of length 0, capacity 0, heatmap=..., this=0x7ffd99beac10) at ../src/contacts/finder.hpp:68
#5  iptsd::core::Application::process_heatmap (this=0x7ffd99bea9e0, data=...) at ../src/core/generic/application.hpp:216
#6  0x000055f6f1f98775 in std::function<void (iptsd::ipts::Heatmap const&)>::operator()(iptsd::ipts::Heatmap const&) const (__args#0=..., this=0x7ffd99beab80) at /usr/include/c++/12.2.1/bits/std_function.h:591
#7  iptsd::ipts::Parser::parse_heatmap_data (reader=<synthetic pointer>..., this=0x7ffd99beab60) at ../src/ipts/parser.hpp:371
#8  iptsd::ipts::Parser::parse_heatmap_frame (reader=..., this=0x7ffd99beab60) at ../src/ipts/parser.hpp:387
#9  iptsd::ipts::Parser::parse_hid (reader=..., this=<optimized out>) at ../src/ipts/parser.hpp:146
#10 iptsd::ipts::Parser::parse_frame (reader=..., this=0x7ffd99beab60) at ../src/ipts/parser.hpp:97
#11 iptsd::ipts::Parser::parse_with_header (header=3, data=..., this=0x7ffd99beab60) at ../src/ipts/parser.hpp:73
#12 iptsd::ipts::Parser::parse<ipts_header> (data=..., this=0x7ffd99beab60) at ../src/ipts/parser.hpp:64
#13 iptsd::ipts::Parser::parse (data=..., this=0x7ffd99beab60) at ../src/ipts/parser.hpp:52
#14 iptsd::core::Application::on_data (data=..., this=0x7ffd99bea9e0) at ../src/core/generic/application.hpp:172
#15 iptsd::core::Application::process (data=..., this=0x7ffd99bea9e0) at ../src/core/generic/application.hpp:152
#16 iptsd::core::linux::DeviceRunner<iptsd::apps::daemon::Daemon>::run (this=0x7ffd99bea980) at ../src/core/linux/device-runner.hpp:116
#17 0x000055f6f1f8d7be in iptsd::apps::daemon::(anonymous namespace)::run (args=...) at ../src/apps/daemon/main.cpp:40
#18 0x000055f6f1f5c0fe in main (argc=2, argv=0x7ffd99bec438) at ../src/apps/daemon/main.cpp:55

core.iptsd.0.9a3aadb07a81419498c8880be2e39327.1232.zip

aktowns commented 1 year ago

Ahh yep im able to reproduce reliably, its when i have my finger on the screen while iptsd is starting, heres a core from a build with -O0 i hopefully has enough info

Program received signal SIGSEGV, Segmentation fault.
iptsd::contacts::detection::convolution::impl::run_3x3<Eigen::Array<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, 3, 3, 1, 3, 3> >(Eigen::DenseBase<Eigen::Array<double, -1, -1, 1, -1, -1> > const&, Eigen::DenseBase<Eigen::Matrix<double, 3, 3, 1, 3, 3> > const&, Eigen::DenseBase<Eigen::Array<double, -1, -1, 1, -1, -1> >&)::{lambda(long, long, long)#2}::operator()(long, long, long) const (__closure=0x7fffffffd470, i=0, dx=0, dy=0)
    at ../src/contacts/detection/algorithms/optimized/convolution.3x3-extend.hpp:49
49          return in.coeff(index);
(gdb) bt
#0  iptsd::contacts::detection::convolution::impl::run_3x3<Eigen::Array<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, 3, 3, 1, 3, 3> >(Eigen::DenseBase<Eigen::Array<double, -1, -1, 1, -1, -1> > const&, Eigen::DenseBase<Eigen::Matrix<double, 3, 3, 1, 3, 3> > const&, Eigen::DenseBase<Eigen::Array<double, -1, -1, 1, -1, -1> >&)::{lambda(long, long, long)#2}::operator()(long, long, long) const (__closure=0x7fffffffd470, i=0, dx=0, dy=0)
    at ../src/contacts/detection/algorithms/optimized/convolution.3x3-extend.hpp:49
#1  0x00005555555d4799 in iptsd::contacts::detection::convolution::impl::run_3x3<Eigen::Array<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, 3, 3, 1, 3, 3> > (in=..., kernel=..., out=...)
    at ../src/contacts/detection/algorithms/optimized/convolution.3x3-extend.hpp:62
#2  0x00005555555c60dc in iptsd::contacts::detection::convolution::run<Eigen::Array<double, -1, -1, 1, -1, -1>, Eigen::Matrix<double, 3, 3, 1, 3, 3> > (in=..., kernel=..., out=...)
    at ../src/contacts/detection/algorithms/convolution.hpp:91
#3  0x00005555555b6fa5 in iptsd::contacts::detection::Detector<double, double>::detect<-1, -1> (this=0x7fffffffe400, heatmap=..., contacts=std::vector of length 0, capacity 0) at ../src/contacts/detection/detector.hpp:115
#4  0x00005555555a9707 in iptsd::contacts::Finder<double, double>::find<-1, -1> (this=0x7fffffffe400, heatmap=..., contacts=std::vector of length 0, capacity 0) at ../src/contacts/finder.hpp:70
#5  0x00005555555825fa in iptsd::core::Application::process_heatmap (this=0x7fffffffe1d0, data=...) at ../src/core/generic/application.hpp:216
#6  0x000055555558199e in auto iptsd::core::Application::Application(iptsd::core::Config const&, iptsd::core::DeviceInfo const&, std::optional<iptsd::ipts::Metadata const>)::{lambda(auto:1 const&)#1}::operator()<iptsd::ipts::Heatmap>(iptsd::ipts::Heatmap const&) const () at ../src/core/generic/application.hpp:138
#7  0x00005555555e484b in std::__invoke_impl<void, iptsd::core::Application::Application(iptsd::core::Config const&, iptsd::core::DeviceInfo const&, std::optional<iptsd::ipts::Metadata const>)::{lambda(auto:1 const&)#1}&, iptsd::ipts::Heatmap const&>(std::__invoke_other, iptsd::core::Application::Application(iptsd::core::Config const&, iptsd::core::DeviceInfo const&, std::optional<iptsd::ipts::Metadata const>)::{lambda(auto:1 const&)#1}&, iptsd::ipts::Heatmap const&) (__f=...) at /usr/include/c++/12.2.1/bits/invoke.h:61
#8  0x00005555555d3a95 in std::__invoke_r<void, iptsd::core::Application::Application(iptsd::core::Config const&, iptsd::core::DeviceInfo const&, std::optional<iptsd::ipts::Metadata const>)::{lambda(auto:1 const&)#1}&, iptsd::ipts::Heatmap const&>(iptsd::core::Application::Application(iptsd::core::Config const&, iptsd::core::DeviceInfo const&, std::optional<iptsd::ipts::Metadata const>)::{lambda(auto:1 const&)#1}&, iptsd::ipts::Heatmap const&) (__fn=...)
    at /usr/include/c++/12.2.1/bits/invoke.h:111
#9  0x00005555555c559e in std::_Function_handler<void (iptsd::ipts::Heatmap const&), iptsd::core::Application::Application(iptsd::core::Config const&, iptsd::core::DeviceInfo const&, std::optional<iptsd::ipts::Metadata const>)::{lambda(auto:1 const&)#1}>::_M_invoke(std::_Any_data const&, iptsd::ipts::Heatmap const&) (__functor=..., __args#0=...) at /usr/include/c++/12.2.1/bits/std_function.h:290
#10 0x00005555555a694b in std::function<void (iptsd::ipts::Heatmap const&)>::operator()(iptsd::ipts::Heatmap const&) const (this=0x7fffffffe370, __args#0=...) at /usr/include/c++/12.2.1/bits/std_function.h:591
#11 0x000055555557abe5 in iptsd::ipts::Parser::parse_heatmap_data (this=0x7fffffffe350, reader=...) at ../src/ipts/parser.hpp:371
#12 0x000055555557ac59 in iptsd::ipts::Parser::parse_heatmap_frame (this=0x7fffffffe350, reader=...) at ../src/ipts/parser.hpp:387
#13 0x000055555557a485 in iptsd::ipts::Parser::parse_hid (this=0x7fffffffe350, reader=...) at ../src/ipts/parser.hpp:146
#14 0x000055555557a2ee in iptsd::ipts::Parser::parse_frame (this=0x7fffffffe350, reader=...) at ../src/ipts/parser.hpp:97
#15 0x000055555557a20f in iptsd::ipts::Parser::parse_with_header (this=0x7fffffffe350, data=..., header=3) at ../src/ipts/parser.hpp:73
#16 0x00005555555a6153 in iptsd::ipts::Parser::parse<ipts_header> (this=0x7fffffffe350, data=...) at ../src/ipts/parser.hpp:64
#17 0x000055555557a19f in iptsd::ipts::Parser::parse (this=0x7fffffffe350, data=...) at ../src/ipts/parser.hpp:52
#18 0x0000555555582353 in iptsd::core::Application::on_data (this=0x7fffffffe1d0, data=...) at ../src/core/generic/application.hpp:172
#19 0x00005555555822f7 in iptsd::core::Application::process (this=0x7fffffffe1d0, data=...) at ../src/core/generic/application.hpp:152
#20 0x00005555555b2107 in iptsd::core::linux::DeviceRunner<iptsd::apps::daemon::Daemon>::run (this=0x7fffffffe170) at ../src/core/linux/device-runner.hpp:116
#21 0x00005555555a42fa in iptsd::apps::daemon::(anonymous namespace)::run (args=...) at ../src/apps/daemon/main.cpp:40
#22 0x00005555555a45cd in main (argc=2, argv=0x7fffffffec18) at ../src/apps/daemon/main.cpp:55

core.zip

StollD commented 1 year ago

It doesnt really look like the same error, because the first error was an assertion (so the index was checked) and the second error is from bypassing the access check on purpose.

Nonetheless, I think the root cause of both should be the same.

Could you try to capture a binary log with iptsd-dump again, while reproducing it? You can check if the log contains the issue by running iptsd-perf data.bin.

EDIT: Also the core dumps don't work on my system, so a data dump that shows the issue would help a lot.

aktowns commented 1 year ago

ahh :(

I've tried catching a few dumps where the daemon has died but running iptsd-perf on the resulting iptsd-dump file doesn't crash or appear to break anything

[ash@surfacepro ~]$ iptsd-perf dump.bin 
[10:23:28.541] [info] Metadata:
[10:23:28.541] [info] rows=46, columns=68
[10:23:28.541] [info] width=27389, height=18259
[10:23:28.541] [info] transform=[408.79105,0,0,0,405.75555,0]
[10:23:28.541] [info] unknown=1, [178,182,180,1,178,182,180,1,90,171,100,20,172,177,175,2]
[10:23:28.541] [info] Loaded from device 045E:0C37
[10:23:28.573] [info] Ran 1820 times
[10:23:28.573] [info] Total: 30326μs
[10:23:28.573] [info] Mean: 16.66μs
[10:23:28.573] [info] Standard Deviation: 3.29μs
[10:23:28.573] [info] Minimum: 13.516μs
[10:23:28.573] [info] Maximum: 49.584μs
StollD commented 1 year ago

Thats really weird.

I went back to the backtrace you posted above and looked closer at it. It fails at accessing index 0 of the input data during convolution, so this means that the incoming heatmap is empty. I dont think we have ever checked for this, but it sounds like a good idea.

if (rows == 0 || cols == 0)
        return;

Could you add this code at this line: https://github.com/linux-surface/iptsd/blob/master/src/core/generic/application.hpp#L198? That should fix the segmentation fault. I am still confused about whether the assertion error and the segfault are the same, because iptsd should bypass the access check in that part of the code (unless you force it).

rotech commented 1 year ago

I have been having this error on my SL4 (Intel) with the touchscreen stopping working intermittently, usually when waking from sleep, but not always.

iptsd: /usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:427: Eigen::DenseCoeffsBase<type-parameter-0-0, 1>::Scalar &Eigen::DenseCoeffsBase<Eigen::Array<double, -1, -1, 1>, 1>::operator()(Eigen::Index) [Derived = Eigen::Array<double, -1, -1, 1>, Level = 1]: Assertion `index >= 0 && index < size()' failed.

So far, adding the code has resolved the problem.

aktowns commented 1 year ago

The code change has also resolved the issue for me, i'm unable to replicate it and have not seen it popup after a few hours of use today

StollD commented 1 year ago

The fix was released in iptsd 1.2.1