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

Segfault when watching Gst Element events #157

Closed
MayamaTakeshi opened this issue Feb 17, 2020 · 4 comments · Fixed by #162
Closed

Segfault when watching Gst Element events #157

MayamaTakeshi opened this issue Feb 17, 2020 · 4 comments · Fixed by #162

Comments

@MayamaTakeshi
Copy link

MayamaTakeshi commented Feb 17, 2020

Based on examples/gst.js, I am trying to setup a gstreamer pipeline to detect DTMF digits from a wav file.
I know this should work because I did this:

  1. First I created the DTMF file containing digits 1234:
$ sox '|sox -np trim 0.0 0.200000 rate 8000' '|sox -np synth 0.1 sine 697 sine 1209 channels 1 rate 8000' '|sox -np trim 0.0 0.100000 rate 8000' '|sox -np synth 0.1 sine 697 sine 1336 channels 1 rate 8000' '|sox -np trim 0.0 0.100000 rate 8000' '|sox -np synth 0.1 sine 697 sine 1477 channels 1 rate 8000' '|sox -np trim 0.0 0.100000 rate 8000' '|sox -np synth 0.1 sine 770 sine 1209 channels 1 rate 8000' '|sox -np trim 0.0 0.200000 rate 8000' in.wav
  1. Then I confirmed the format of the wav file:
$ sox --i in.wav 

Input File     : 'in.wav'
Channels       : 1
Sample Rate    : 8000
Precision      : 32-bit
Duration       : 00:00:01.10 = 8800 samples ~ 82.5 CDDA sectors
File Size      : 35.3k
Bit Rate       : 257k
Sample Encoding: 32-bit Signed Integer PCM
  1. Then I confirmed the pipeline works:
$ gst-launch-1.0 -m filesrc location=./in.wav ! decodebin ! audioconvert ! dtmfdetect ! filesink location=./out.wav |grep dtmf-event
Got message #80 from element "dtmfdetect0" (element): dtmf-event, type=(int)1, number=(int)1, method=(int)2;
Got message #81 from element "dtmfdetect0" (element): dtmf-event, type=(int)1, number=(int)2, method=(int)2;
Got message #82 from element "dtmfdetect0" (element): dtmf-event, type=(int)1, number=(int)3, method=(int)2;
Got message #83 from element "dtmfdetect0" (element): dtmf-event, type=(int)1, number=(int)4, method=(int)2;
  1. Then I wrote the node js code:
$ cat detect_dtmf.js 
const gi = require('node-gtk')
const Gst = gi.require('Gst', '1.0')
const Gtk = gi.require('Gtk', '3.0')

gi.startLoop()
Gst.init()

const gstVersion = Gst.version()
console.log(`Gstreamer Version: ${gstVersion[0]}.${gstVersion[1]}.${gstVersion[2]}`)

var pipeline = new Gst.Pipeline("pipeline1")

pipeline.on('child-added', (element, name) => {
    console.log('child-added:', element, name)
})

var src = Gst.ElementFactory.make("filesrc", "src")
var db = Gst.ElementFactory.make("decodebin", "db")
var ac = Gst.ElementFactory.make("audioconvert", "ac")
var dd = Gst.ElementFactory.make("dtmfdetect", "dd")
var sink = Gst.ElementFactory.make("filesink", "sink")

src.location = "./in.wav"
sink.location = "./out.wav"

dd.on('dtmf-event', digit => {
        console.log(`digit: ${digit}`)
})

pipeline.add(src)
pipeline.add(db)
pipeline.add(ac)
pipeline.add(dd)
pipeline.add(sink)

src.link(db)
db.link(ac)
ac.link(dd)
dd.link(sink)

pipeline.setState(Gst.State.PLAYING)

Gtk.main()
  1. But when I try to run it I get a segfault:
$ node detect_dtmf.js
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
Gstreamer Version: 1.14.4
Segmentation fault
  1. But if I remove the
  dd.on('dtmf-event', ...) 

, the segfault doesn't happen:

$ node detect_dtmf.js 
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
[WARN] boxed.cc: BoxedDestroyed: 235: boxed possibly not freed (GIRepository.Typelib : void)
Gstreamer Version: 1.14.4
child-added: GstElement { location: './in.wav' } src
child-added: GstElement {} db
child-added: GstElement {} ac
child-added: GstElement {} dd
child-added: GstElement { location: './out.wav' } sink
  1. running the app on gdb, 'bt full' confirms the problem:
#0  0x00007ffff50470c0 in g_base_info_ref () at /lib/x86_64-linux-gnu/libgirepository-1.0.so.1
#1  0x00007ffff509d573 in GNodeJS::FindSignalInfo (signal_detail=0x7fffffffd420 "dtmf-event", info=0x0) at ../src/gobject.cc:214
        signal_name = 0x2d5fbb0 "dtmf-event"
        signal_info = 0x0
        parent = <optimized out>
        gobject = 0x34b2140
        signal_name = 0x7fffffffd420 "dtmf-event"
        object_info = 0x0
        signal_info = <optimized out>
#2  0x00007ffff509d573 in GNodeJS::SignalConnectInternal(Nan::FunctionCallbackInfo<v8::Value> const&, bool) (info=..., after=false) at ../src/gobject.cc:277
        gobject = 0x34b2140
        signal_name = 0x7fffffffd420 "dtmf-event"
        object_info = 0x0
        signal_info = <optimized out>
#3  0x00007ffff509b558 in Nan::imp::FunctionCallbackWrapper(v8::FunctionCallbackInfo<v8::Value> const&) (info=...) at ../node_modules/nan/nan_callbacks_12_inl.h:176
        obj = {val_ = 0x7fffffffd998}
        callback = 0x7ffff509d920 <GNodeJS::SignalConnect(Nan::FunctionCallbackInfo<v8::Value> const&)>
        cbinfo = 
          {info_ = @0x7fffffffd910, data_ = {val_ = 0x2aeb6c8}, static kHolderIndex = <optimized out>, static kIsolateIndex = <optimized out>, static kReturnValueDefaultValueIndex = <optimized out>, static kReturnValueIndex = <optimized out>, static kDataIndex = <optimized out>, static kCalleeIndex = <optimized out>, static kContextSaveIndex = <optimized out>, static kArgsLength = <optimized out>}
#4  0x0000000000ba6fc9 in v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) ()
#5  0x0000000000ba8db7 in v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) ()
#6  0x0000000001376359 in Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit () at ../../deps/v8/../../deps/v8/src/builtins/base.tq:3028
#7  0x00000000012f68a4 in Builtins_InterpreterEntryTrampoline () at ../../deps/v8/../../deps/v8/src/builtins/base.tq:325
#8  0x00002532bc9c04a9 in  ()
#9  0x00003e5fa185b289 in  ()
#10 0x0000000700000000 in  ()
#11 0x00002532bc9c0589 in  ()
#12 0x00000415a2069049 in  ()
#13 0x0000010b8f89b1e1 in  ()
#14 0x00000415a2068511 in  ()
#15 0x00000415a20691a1 in  ()
#16 0x00002532bc9c04a9 in  ()

So it seems we cannot watch for Gst Element events (however it seems the bug even prevented pipeline events to be notified as they should have happened before the crash).

Environment details:

$ cat /etc/issue
Debian GNU/Linux 10 \n \l

$ node -v
v12.14.1

$ uname -a
Linux takeshi-dev1 4.19.0-6-amd64 #1 SMP Debian 4.19.67-2+deb10u2 (2019-11-11) x86_64 GNU/Linux
@romgrk
Copy link
Owner

romgrk commented Feb 27, 2020

I've tried reproducing the issue but I'm getting the error below. Could you share your in.wav file?

$ cat setup.sh                                                                                                                                                      
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
       │ File: setup.sh
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │ #! /bin/bash
   2   │ 
   3   │ set -eu
   4   │ 
   5   │ sox '|sox -np trim 0.0 0.200000 rate 8000' '|sox -np synth 0.1 sine 697 sine 1209 channels 1 rate 8000' '|sox -np trim 0.0 0.100000 rate 8000' '|sox -np synth 0.1 sine 697 sine 1336 channels 1 rate 8000' 
       │ '|sox -np trim 0.0 0.100000 rate 8000' '|sox -np synth 0.1 sine 697 sine 1477 channels 1 rate 8000' '|sox -np trim 0.0 0.100000 rate 8000' '|sox -np synth 0.1 sine 770 sine 1209 channels 1 rate 8000' '|so
       │ x -np trim 0.0 0.200000 rate 8000' in.wav
   6   │ sox --i in.wav
   7   │ gst-launch-1.0 -m filesrc location=./in.wav ! decodebin ! audioconvert ! dtmfdetect ! filesink location=./out.wav | grep dtmf-event
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

$ ./setup.sh                                                                                                                                                            

Input File     : 'in.wav'
Channels       : 1
Sample Rate    : 8000
Precision      : 32-bit
Duration       : 00:00:01.10 = 8800 samples ~ 82.5 CDDA sectors
File Size      : 35.3k
Bit Rate       : 257k
Sample Encoding: 32-bit Signed Integer PCM

WARNING: erroneous pipeline: no element "dtmfdetect"

@MayamaTakeshi
Copy link
Author

Hi, the problem in this case is that gst-launch is not finding the module containing the element dtmfdetect.
Please try setting the GST_PLUGIN_PATH to the folder where it can be found:

(base) takeshi@takeshi-brastel:tmp$ find /usr -name libgstspandsp.so
/usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstspandsp.so

(base) takeshi@takeshi-brastel:tmp$ export GST_PLUGIN_PATH=/usr/lib/x86_64-linux-gnu/gstreamer-1.0

Obs: if libgstspandsp.so cannot be found, it is because you don't have gst-plugins-bad installed.

@romgrk
Copy link
Owner

romgrk commented Mar 2, 2020

Got it, I'm able to reproduce the issue. A g_irepository_find_by_gtype() call is returning NULL, here is what the doc has to say about that:

Searches all loaded namespaces for a particular GType. Note that in order to locate the metadata, the namespace corresponding to the type must first have been loaded. There is currently no mechanism for determining the namespace which corresponds to an arbitrary GType - thus, this function will operate most reliably when you know the GType to originate from be from a loaded namespace.

The GType for which it's trying to locate the data is GstDtmfDetect. I've tried requiring all GstXxxxx modules that I could find but couldn't find the one containing the metadata for this symbol. The search results on Google or searchcode for GstDtmfDetect are also quite sparse, couldn't find any documentation for that particular symbol. If someone has a suggestion I'd be happy to hear it.

Meanwhile I'll throw an error with a more helpful message when this case hits.

@romgrk
Copy link
Owner

romgrk commented Mar 3, 2020

This is closed because the error is now handled properly. The missing module might be an upstream bug (eg missing dependency in required dependencies). If you think it should still be fixed here please open a new issue (eg Missing module for GstDtmfDetect), I'll be happy to assist as much as I can. And if you find the solution let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants